[
  {
    "path": ".config/tsaoptions.json",
    "content": "{  \n    \"instanceUrl\": \"https://dev.azure.com/devdiv/\",\n    \"template\": \"TFSDEVDIV\",\n    \"projectName\": \"DEVDIV\",\n    \"areaPath\": \"DevDiv\\\\Web Tools\\\\API\\\\Http Repl\",\n    \"iterationPath\": \"DevDiv\",\n    \"notificationAliases\": [ \"webproject@microsoft.com\" ],\n    \"repositoryName\":\"HttpRepl\",\n    \"codebaseName\": \"HttpRepl\",\n    \"serviceTreeId\": \"225159cd-5cda-4eaf-9b48-9bc4ff385b23\"\n}\n"
  },
  {
    "path": ".editorconfig",
    "content": "# EditorConfig is awesome:http://EditorConfig.org\n\n# top-most EditorConfig file\nroot = true\n\n[*]\n# Don't use tabs for indentation.\n# (Please don't specify an indent_size here; that has too many unintended consequences.)\nindent_style = space\n\ncharset = utf-8\n\n# Where supported, trim trailing whitespace on all lines.\ntrim_trailing_whitespace = true\n\n# Where supported (e.g. in VS Code but not VS), add a final newline to files.\ninsert_final_newline = true\n\n# Code files\n[*.{cs,csx,vb,vbx}]\nindent_size = 4\ndotnet_sort_system_directives_first = true:warning\n\nfile_header_template = Licensed to the .NET Foundation under one or more agreements.\\nThe .NET Foundation licenses this file to you under the MIT license.\\nSee the License.txt file in the project root for more information.\n\n# Xml project files\n[*.{*proj,vcxproj.filters,projitems}]\nindent_size = 2\n\n# Xml config files\n[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct,tasks,xml,yml}]\nindent_size = 2\n\n# JSON files\n[*.json]\nindent_size = 2\n\n# PowerShell\n[*.{ps1,psm1}]\nindent_size = 4\n\n# Shell\n[*.sh]\nindent_size = 4\nend_of_line = lf\n\n# Dotnet code style settings:\n[*.cs]\n# Sort using and Import directives with System.* appearing first\ndotnet_sort_system_directives_first = true\n\n# Don't use this. qualifier\ndotnet_style_qualification_for_field = false:suggestion\ndotnet_style_qualification_for_property = false:suggestion\n\n# use int x = .. over Int32\ndotnet_style_predefined_type_for_locals_parameters_members = true:suggestion\n\n# use int.MaxValue over Int32.MaxValue\ndotnet_style_predefined_type_for_member_access = true:suggestion\n\n# Require var all the time.\ncsharp_style_var_for_built_in_types = false:suggestion\ncsharp_style_var_when_type_is_apparent = false:suggestion\ncsharp_style_var_elsewhere = false:suggestion\n\n# Disallow throw expressions.\ncsharp_style_throw_expression = false:suggestion\n\n# Newline settings\ncsharp_new_line_before_open_brace = all\ncsharp_new_line_before_else = true\ncsharp_new_line_before_catch = true\ncsharp_new_line_before_finally = true\ncsharp_new_line_before_members_in_object_initializers = true\ncsharp_new_line_before_members_in_anonymous_types = true\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto\n*.cs diff=csharp\n*.sh eol=lf\n*.sln eol=crlf\n"
  },
  {
    "path": ".gitignore",
    "content": "syntax: glob\n\n### VisualStudio ###\n\n# Tools directory\n/[Tt]ools/\n.dotnet/\n.packages/\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\nlaunchSettings.json\n\n# Build results\n\nartifacts/\n[Dd]ebug/\n[Rr]elease/\nx64/\nx86/ !eng/common/cross/x86/\n[Bb]in/\n[Oo]bj/\nmsbuild.log\nmsbuild.err\nmsbuild.wrn\nmsbuild.binlog\n\n# Visual Studio 2015\n.vs/\n\n# Visual Studio 2015 Pre-CTP6\n*.sln.ide\n*.ide/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n#NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NuGet Packages\n*.nuget.props\n*.nuget.targets\n*.nupkg\n**/packages/*\n\n### Windows ###\n\n# Windows image file caches\nThumbs.db\nehthumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n### Linux ###\n\n*~\n\n# KDE directory preferences\n.directory\n\n### OSX ###\n\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear on external disk\n.Spotlight-V100\n.Trashes\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n# vim temporary files\n[._]*.s[a-w][a-z]\n[._]s[a-w][a-z]\n*.un~\nSession.vim\n.netrwhist\n*~\n\n# Visual Studio Code\n.vscode/\n\n# Private test configuration and binaries.\nconfig.ps1\n**/IISApplications\n\n\n# Node.js modules\nnode_modules/\n\n# Python Compile Outputs\n\n*.pyc"
  },
  {
    "path": "CODE-OF-CONDUCT.md",
    "content": "# Code of Conduct\n\nThis project has adopted the code of conduct defined by the Contributor Covenant\nto clarify expected behavior in our community.\n\nFor more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# How to contribute\n\nOne of the easiest ways to contribute is to participate in discussions on GitHub issues. You can also contribute by submitting pull requests with code changes.\n\n## General feedback, bugs, feature requests and discussions?\nStart a discussion on the [repository issue tracker](https://github.com/aspnet/HttpRepl/issues).\n\n## Reporting security issues and bugs\n\nSecurity issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC)  secure@microsoft.com. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the [Security TechCenter](https://technet.microsoft.com/en-us/security/ff852094.aspx).\n\n## Contributing code and content\n\nWe accept fixes and features! \n\n* Look at the [README](/README.md) to get started on building the source code on your own.\n* Submit a PR when you're ready and we'll take a look!\n\n### Submitting a pull request\n\nYou will need to sign a [Contributor License Agreement](https://cla.dotnetfoundation.org/) when submitting your pull request. To complete the Contributor License Agreement (CLA), you will need to follow the instructions provided by the CLA bot when you send the pull request. This needs to only be done once for any .NET Foundation OSS project.\n\nIf you don't know what a pull request is read this article: https://help.github.com/articles/using-pull-requests. Make sure the repository can build and all tests pass. Familiarize yourself with the project workflow and our coding conventions. The coding, style, and general engineering guidelines are published on the [Engineering guidelines](https://github.com/aspnet/AspNetCore/wiki/Engineering-guidelines) page.\n\n### Tests\n\n-  Tests need to be provided for every bug/feature that is completed.\n-  Tests only need to be present for issues that need to be verified by QA (for example, not tasks)\n-  If there is a scenario that is far too hard to test there does not need to be a test for it.\n  - \"Too hard\" is determined by the team as a whole.\n\n### Feedback\n\nYour pull request will now go through extensive checks by the subject matter experts on our team. Please be patient; we have hundreds of pull requests across all of our repositories. Update your pull request according to feedback until it is approved by one of the team members. After that, one of our team members may adjust the branch you merge into based on the expected release schedule.\n"
  },
  {
    "path": "Directory.Build.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project>\n  <!-- Leave this file here, even if it's empty. It stops chaining imports. -->\n\n  <Import Project=\"Sdk.props\" Sdk=\"Microsoft.DotNet.Arcade.Sdk\" />\n\n  <PropertyGroup>\n    <LangVersion>preview</LangVersion>\n    <HighEntropyVa>true</HighEntropyVa>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <RepoRoot Condition=\" '$(RepoRoot)' == '' \">$(MSBuildThisFileDirectory)</RepoRoot>\n    <RepoSource Condition=\" '$(RepoSource)' == '' \">$(RepoRoot)src</RepoSource>\n    <RepoTest Condition=\" '$(RepoTest)' == '' \">$(RepoRoot)test</RepoTest>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(CopyrightNetFoundation)' != ''\">\n    <Copyright>$(CopyrightMicrosoft)</Copyright>\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "Directory.Build.targets",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project>\n  <!-- Leave this file here, even if it's empty. It stops chaining imports. -->\n  <Import Project=\"Sdk.targets\" Sdk=\"Microsoft.DotNet.Arcade.Sdk\" />\n</Project>\n"
  },
  {
    "path": "Directory.Packages.props",
    "content": "<Project>\n  <PropertyGroup>\n    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>\n    <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>\n    <!-- Suppress this warning until Arcade has better support -->\n    <NoWarn>$(NoWarn);NU1507</NoWarn>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageVersion Include=\"Microsoft.ApplicationInsights.WorkerService\" Version=\"2.20.0\" />\n    <PackageVersion Include=\"Microsoft.AspNet.WebApi.Client\" Version=\"5.2.7\" />\n    <PackageVersion Include=\"Microsoft.CodeAnalysis.FxCopAnalyzers\" Version=\"3.3.1\" />\n    <PackageVersion Include=\"Microsoft.DotNet.PlatformAbstractions\" Version=\"3.1.6\" />\n    <PackageVersion Include=\"Microsoft.OpenApi.Readers\" Version=\"1.2.3\" />\n    <PackageVersion Include=\"Microsoft.Win32.Registry\" Version=\"5.0.0\" />\n    <PackageVersion Include=\"Moq\" Version=\"4.14.7\" />\n    <PackageVersion Include=\"Newtonsoft.Json\" Version=\"13.0.1\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore\" Version=\"6.4.0\" />\n    <PackageVersion Include=\"System.Net.Http\" Version=\"4.3.4\" />\n    <PackageVersion Include=\"System.Diagnostics.Process\" Version=\"4.3.0\" />\n    <PackageVersion Include=\"System.Private.Uri\" Version=\"4.3.2\" />\n    <PackageVersion Include=\"System.Text.Encoding.CodePages\" Version=\"5.0.0\" />\n    <PackageVersion Include=\"System.Threading.Thread\" Version=\"4.3.0\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <!--\n      This PackageVersion is only here to deal with a Component Governance alert.\n      Once Microsoft.ApplicationInsights.WorkerService 2.22 is released, we can\n      update our reference to that and remove this.\n    -->\n    <PackageVersion Include=\"System.Drawing.Common\" Version=\"4.7.2\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "HttpRepl.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 16\r\nVisualStudioVersion = 16.0.29006.145\r\nMinimumVisualStudioVersion = 15.0.26124.0\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.HttpRepl.Tests\", \"test\\Microsoft.HttpRepl.Tests\\Microsoft.HttpRepl.Tests.csproj\", \"{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.HttpRepl\", \"src\\Microsoft.HttpRepl\\Microsoft.HttpRepl.csproj\", \"{798BD900-DFF5-46CD-A422-5B0B2495A943}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.Repl.Tests\", \"test\\Microsoft.Repl.Tests\\Microsoft.Repl.Tests.csproj\", \"{218B878C-5856-4B1F-99B7-8D98AB4C1B03}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.Repl\", \"src\\Microsoft.Repl\\Microsoft.Repl.csproj\", \"{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.HttpRepl.IntegrationTests\", \"test\\Microsoft.HttpRepl.IntegrationTests\\Microsoft.HttpRepl.IntegrationTests.csproj\", \"{A1B13133-8F4D-42D5-B470-D6349C71AFD6}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.HttpRepl.Fakes\", \"test\\Microsoft.HttpRepl.Fakes\\Microsoft.HttpRepl.Fakes.csproj\", \"{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.HttpRepl.Telemetry\", \"src\\Microsoft.HttpRepl.Telemetry\\Microsoft.HttpRepl.Telemetry.csproj\", \"{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Any CPU = Debug|Any CPU\r\n\t\tDebug|x64 = Debug|x64\r\n\t\tDebug|x86 = Debug|x86\r\n\t\tRelease|Any CPU = Release|Any CPU\r\n\t\tRelease|x64 = Release|x64\r\n\t\tRelease|x86 = Release|x86\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{84E7BEDA-9064-4B11-A84B-3011C6A97A8C}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{798BD900-DFF5-46CD-A422-5B0B2495A943}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{218B878C-5856-4B1F-99B7-8D98AB4C1B03}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{AC0BF0EE-FF72-4BD8-BF18-3322BE5FA695}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{A1B13133-8F4D-42D5-B470-D6349C71AFD6}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{32DEC29F-4FFB-4AFB-8E9E-A88B44739CC4}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{EE2A1FCB-F93B-4FF1-BD37-95A1E4991AD1}.Release|x86.Build.0 = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n\t\tSolutionGuid = {7D2700BF-2B16-46BC-9761-E941C506AC69}\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "The MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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"
  },
  {
    "path": "NOTICE.txt",
    "content": "NOTICES AND INFORMATION\nDo Not Translate or Localize\n\nThis software incorporates material from third parties.\nMicrosoft makes certain open source code available at https://3rdpartysource.microsoft.com,\nor you may send a check or money order for US $5.00, including the product name,\nthe open source component name, platform, and version number, to:\n\nSource Code Compliance Team\nMicrosoft Corporation\nOne Microsoft Way\nRedmond, WA 98052\nUSA\n\nNotwithstanding any other terms, you may reverse engineer this software to the extent\nrequired to debug changes to any libraries licensed under the GNU Lesser General Public License.\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.Configuration 2.1.1 - Apache-2.0\n\n\n(c) Microsoft Corporation.\n\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \n\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\n\n      \n\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n      \n\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n      \n\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\n\n      \n\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\n\n      \n\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n      \n\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\n\n      \n\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\n\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\n\nyou may not use this file except in compliance with the License.\n\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\n\ndistributed under the License is distributed on an \"AS IS\" BASIS,\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\nSee the License for the specific language governing permissions and\n\nlimitations under the License.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.Configuration.Abstractions 2.1.1 - Apache-2.0\n\n\n(c) Microsoft Corporation.\n\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \n\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\n\n      \n\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n      \n\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n      \n\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\n\n      \n\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\n\n      \n\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n      \n\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\n\n      \n\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\n\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\n\nyou may not use this file except in compliance with the License.\n\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\n\ndistributed under the License is distributed on an \"AS IS\" BASIS,\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\nSee the License for the specific language governing permissions and\n\nlimitations under the License.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.Configuration.Binder 2.1.1 - Apache-2.0\n\n\n(c) Microsoft Corporation.\n\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \n\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\n\n      \n\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n      \n\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n      \n\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\n\n      \n\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\n\n      \n\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n      \n\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\n\n      \n\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\n\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\n\nyou may not use this file except in compliance with the License.\n\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\n\ndistributed under the License is distributed on an \"AS IS\" BASIS,\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\nSee the License for the specific language governing permissions and\n\nlimitations under the License.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.DependencyInjection 2.1.1 - Apache-2.0\n\n\n(c) Microsoft Corporation.\n\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \n\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\n\n      \n\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n      \n\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n      \n\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\n\n      \n\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\n\n      \n\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n      \n\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\n\n      \n\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\n\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\n\nyou may not use this file except in compliance with the License.\n\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\n\ndistributed under the License is distributed on an \"AS IS\" BASIS,\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\nSee the License for the specific language governing permissions and\n\nlimitations under the License.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.DependencyInjection.Abstractions 2.1.1 - Apache-2.0\n\n\n(c) Microsoft Corporation.\n\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \n\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\n\n      \n\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n      \n\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n      \n\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\n\n      \n\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\n\n      \n\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n      \n\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\n\n      \n\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\n\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\n\nyou may not use this file except in compliance with the License.\n\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\n\ndistributed under the License is distributed on an \"AS IS\" BASIS,\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\nSee the License for the specific language governing permissions and\n\nlimitations under the License.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.Logging 2.1.1 - Apache-2.0\n\n\n(c) Microsoft Corporation.\n\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \n\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\n\n      \n\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n      \n\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n      \n\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\n\n      \n\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\n\n      \n\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n      \n\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\n\n      \n\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\n\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\n\nyou may not use this file except in compliance with the License.\n\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\n\ndistributed under the License is distributed on an \"AS IS\" BASIS,\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\nSee the License for the specific language governing permissions and\n\nlimitations under the License.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.Logging.Abstractions 2.1.1 - Apache-2.0\n\n\n(c) Microsoft Corporation.\n\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \n\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\n\n      \n\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n      \n\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n      \n\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\n\n      \n\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\n\n      \n\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n      \n\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\n\n      \n\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\n\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\n\nyou may not use this file except in compliance with the License.\n\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\n\ndistributed under the License is distributed on an \"AS IS\" BASIS,\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\nSee the License for the specific language governing permissions and\n\nlimitations under the License.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.Options 2.1.1 - Apache-2.0\n\n\n(c) Microsoft Corporation.\n\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \n\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\n\n      \n\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n      \n\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n      \n\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\n\n      \n\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\n\n      \n\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n      \n\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\n\n      \n\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\n\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\n\nyou may not use this file except in compliance with the License.\n\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\n\ndistributed under the License is distributed on an \"AS IS\" BASIS,\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\nSee the License for the specific language governing permissions and\n\nlimitations under the License.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.Primitives 2.1.1 - Apache-2.0\n\n\n(c) Microsoft Corporation.\n\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \n\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\n\n      \n\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n      \n\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n      \n\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\n\n      \n\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\n\n      \n\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n      \n\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\n\n      \n\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\n\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\n\nyou may not use this file except in compliance with the License.\n\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\n\ndistributed under the License is distributed on an \"AS IS\" BASIS,\n\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\nSee the License for the specific language governing permissions and\n\nlimitations under the License.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.ApplicationInsights 2.20.0 - MIT\n\n\n(c) Microsoft Corporation\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.ApplicationInsights.DependencyCollector 2.20.0 - MIT\n\n\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.ApplicationInsights.EventCounterCollector 2.20.0 - MIT\n\n\n(c) Microsoft Corporation.\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.ApplicationInsights.PerfCounterCollector 2.20.0 - MIT\n\n\n(c) Microsoft Corporation.\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.ApplicationInsights.WindowsServer 2.20.0 - MIT\n\n\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.ApplicationInsights.WindowsServer.TelemetryChannel 2.20.0 - MIT\n\n\n(c) Microsoft Corporation.\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.ApplicationInsights.WorkerService 2.20.0 - MIT\n\n\n(c) Microsoft Corporation.\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.DotNet.PlatformAbstractions 3.1.6 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) Andrew Arnott\nCopyright (c) 2011, Google Inc.\nCopyright (c) 1998 Microsoft. To\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 2017 Yoshifumi Kawai\nCopyright (c) Microsoft Corporation\nCopyright (c) 2012-2014, Yann Collet\nCopyright (c) 1991-2017 Unicode, Inc.\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) The Internet Society 1997.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) 2013-2017, Milosz Krajewski\nCopyright (c) .NET Foundation Contributors\nCopyright (c) The Internet Society (2003).\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\nCopyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass.\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Extensions.Logging.ApplicationInsights 2.20.0 - MIT\n\n\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.OpenApi 1.2.3 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) Microsoft Corporation.\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nMicrosoft.Win32.SystemEvents 4.7.0 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) .NET Foundation.\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 2007 James Newton-King\nCopyright (c) 1991-2017 Unicode, Inc.\nCopyright (c) 2013-2017, Alfred Klomp\nCopyright (c) 2015-2017, Wojciech Mula\nCopyright (c) 2005-2007, Nick Galbreath\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) 2016-2017, Matthieu Darbois\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nNewtonsoft.Json 13.0.1 - MIT\n\n\nCopyright James Newton-King 2008\nCopyright (c) 2007 James Newton-King\nCopyright (c) James Newton-King 2008\nCopyright James Newton-King 2008 Json.NET\n\nThe MIT License (MIT)\n\nCopyright (c) 2007 James Newton-King\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject 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, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSharpYaml 1.6.5 - MIT\n\n\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSystem.Configuration.ConfigurationManager 4.7.0 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) .NET Foundation.\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 2007 James Newton-King\nCopyright (c) 1991-2017 Unicode, Inc.\nCopyright (c) 2013-2017, Alfred Klomp\nCopyright (c) 2015-2017, Wojciech Mula\nCopyright (c) 2005-2007, Nick Galbreath\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) 2016-2017, Matthieu Darbois\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSystem.Diagnostics.PerformanceCounter 4.7.0 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) .NET Foundation.\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 2007 James Newton-King\nCopyright (c) 1991-2017 Unicode, Inc.\nCopyright (c) 2013-2017, Alfred Klomp\nCopyright (c) 2015-2017, Wojciech Mula\nCopyright (c) 2005-2007, Nick Galbreath\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) 2016-2017, Matthieu Darbois\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSystem.Drawing.Common 4.7.2 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) .NET Foundation.\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 2007 James Newton-King\nCopyright (c) 1991-2017 Unicode, Inc.\nCopyright (c) 2013-2017, Alfred Klomp\nCopyright (c) 2015-2017, Wojciech Mula\nCopyright (c) 2005-2007, Nick Galbreath\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) 2016-2017, Matthieu Darbois\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSystem.IO.FileSystem.AccessControl 4.7.0 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) .NET Foundation.\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 2007 James Newton-King\nCopyright (c) 1991-2017 Unicode, Inc.\nCopyright (c) 2013-2017, Alfred Klomp\nCopyright (c) 2015-2017, Wojciech Mula\nCopyright (c) 2005-2007, Nick Galbreath\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) 2016-2017, Matthieu Darbois\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSystem.Memory 4.5.1 - MIT\n\n\n(c) Microsoft Corporation\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson\nCopyright (c) 1991-2017 Unicode, Inc.\nCopyright (c) 2015 The Chromium Authors\nPortions (c) International Organization\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSystem.Runtime.CompilerServices.Unsafe 4.5.1 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 1991-2017 Unicode, Inc.\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSystem.Security.Cryptography.ProtectedData 4.7.0 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) .NET Foundation.\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 2007 James Newton-King\nCopyright (c) 1991-2017 Unicode, Inc.\nCopyright (c) 2013-2017, Alfred Klomp\nCopyright (c) 2015-2017, Wojciech Mula\nCopyright (c) 2005-2007, Nick Galbreath\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) 2016-2017, Matthieu Darbois\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSystem.Security.Permissions 4.7.0 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) .NET Foundation.\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 2007 James Newton-King\nCopyright (c) 1991-2017 Unicode, Inc.\nCopyright (c) 2013-2017, Alfred Klomp\nCopyright (c) 2015-2017, Wojciech Mula\nCopyright (c) 2005-2007, Nick Galbreath\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) 2016-2017, Matthieu Darbois\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n---------------------------------------------------------\n\nSystem.Windows.Extensions 4.7.0 - MIT\n\n\n(c) Microsoft Corporation.\nCopyright (c) .NET Foundation.\nCopyright (c) 2011, Google Inc.\n(c) 1997-2005 Sean Eron Anderson.\nCopyright (c) 2007 James Newton-King\nCopyright (c) 1991-2017 Unicode, Inc.\nCopyright (c) 2013-2017, Alfred Klomp\nCopyright (c) 2015-2017, Wojciech Mula\nCopyright (c) 2005-2007, Nick Galbreath\nPortions (c) International Organization\nCopyright (c) 2015 The Chromium Authors.\nCopyright (c) 2004-2006 Intel Corporation\nCopyright (c) 2016-2017, Matthieu Darbois\nCopyright (c) .NET Foundation Contributors\nCopyright (c) .NET Foundation and Contributors\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\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\n---------------------------------------------------------\n\n"
  },
  {
    "path": "NuGet.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <clear />\n    <add key=\"dotnet8\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json\" />\n    <add key=\"dotnet8-transport\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8-transport/nuget/v3/index.json\" />\n    <add key=\"dotnet-eng\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json\" />\n    <add key=\"dotnet-tools\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json\" />\n    <add key=\"dotnet-public\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json\" />\n  </packageSources>\n  <disabledPackageSources />\n</configuration>\n"
  },
  {
    "path": "README.md",
    "content": "HttpRepl\n=======\n\n# HttpRepl is now deprecated\n\nHttpRepl is now deprecated and will not receive any future updates. See https://github.com/dotnet/HttpRepl/issues/701 for more info.\n\n\n# Build Status\n\n[![Build Status](https://dev.azure.com/dnceng/public/_apis/build/status/aspnet/HttpRepl/aspnet-HttpRepl-CI?branchName=main)](https://dev.azure.com/dnceng/public/_build/latest?definitionId=538&branchName=main)\n\nThe HTTP Read-Eval-Print Loop (REPL) is:\n\n- A lightweight, cross-platform command-line tool that's supported everywhere .NET Core is supported.\n- Used for making HTTP requests to test ASP.NET Core web APIs and view their results.\n\n## Installation\n\nTo install the HttpRepl, run the following command:\n\n```\ndotnet tool install -g Microsoft.dotnet-httprepl\n```\n\nA [.NET Core Global Tool](https://docs.microsoft.com/dotnet/core/tools/global-tools#install-a-global-tool) is installed from the [Microsoft.dotnet-httprepl](https://www.nuget.org/packages/Microsoft.dotnet-httprepl) NuGet package.\n\n## Usage\n\nSee the [documentation](https://aka.ms/http-repl-doc) for how to use and configure HttpRepl.\n\n## Telemetry\n\nSee the [documentation](https://docs.microsoft.com/aspnet/core/web-api/http-repl/telemetry) for information about the usage data collection.\n\n## Building\n\nTo build this repo, run the `build.cmd` or `build.sh` in the root of this repo. This repo uses the .NET [Arcade toolset](https://github.com/dotnet/arcade).\n\n## Contributing\n\nSee the [Contributing Guide](/CONTRIBUTING.md) for details on what it means to contribute and how to do so.\n\n## Reporting security issues and bugs\n\nSecurity issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) secure@microsoft.com. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the [Security TechCenter](https://technet.microsoft.com/security/ff852094.aspx).\n"
  },
  {
    "path": "SECURITY.md",
    "content": "<!-- BEGIN MICROSOFT SECURITY.MD V0.0.2 BLOCK -->\n\n## Security\n\nMicrosoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [many more](https://opensource.microsoft.com/).\n\nIf you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [definition](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)) of a security vulnerability, please report it to us as described below.\n\n## Reporting Security Issues\n\n**Please do not report security vulnerabilities through public GitHub issues.**\n\nInstead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).\n\nIf you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com).  If possible, encrypt your message with our PGP key; please download it from the the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).\n\nYou should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).\n\nPlease include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:\n\n  * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)\n  * Full paths of source file(s) related to the manifestation of the issue\n  * The location of the affected source code (tag/branch/commit or direct URL)\n  * Any special configuration required to reproduce the issue\n  * Step-by-step instructions to reproduce the issue\n  * Proof-of-concept or exploit code (if possible)\n  * Impact of the issue, including how an attacker might exploit the issue\n\nThis information will help us triage your report more quickly.\n\nIf you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.\n\n## Preferred Languages\n\nWe prefer all communications to be in English.\n\n## Policy\n\nMicrosoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).\n\n<!-- END MICROSOFT SECURITY.MD BLOCK -->\n"
  },
  {
    "path": "azure-pipelines-codeql.yml",
    "content": "parameters:\n  # Optionally do not publish to TSA. Useful for e.g. verifying fixes before PR.\n- name: TSAEnabled\n  displayName: Publish results to TSA\n  type: boolean\n  default: true\n\nvariables:\n- template: eng/common/templates/variables/pool-providers.yml\n  # CG is handled in the primary CI pipeline\n- name: skipComponentGovernanceDetection\n  value: true\n  # Force CodeQL enabled so it may be run on any branch\n- name: Codeql.Enabled\n  value: true\n  # Do not let CodeQL 3000 Extension gate scan frequency\n- name: Codeql.Cadence\n  value: 0\n  # CodeQL needs this plumbed along as a variable to enable TSA\n- name: Codeql.TSAEnabled\n  value: ${{ parameters.TSAEnabled }}\n\n  # Build variables\n- name: _BuildConfig\n  value: Release\n\ntrigger: none\n\nschedules:\n  - cron: 0 12 * * 1\n    displayName: Weekly Monday CodeQL run\n    branches:\n      include:\n      - main\n    always: true\n\njobs:\n- job: codeql\n  displayName: CodeQL\n  pool:\n    name: VSEngSS-MicroBuild2022-1ES\n  timeoutInMinutes: 90\n\n  steps:\n\n  - task: UseDotNet@2\n    inputs:\n      useGlobalJson: true\n\n  - task: CodeQL3000Init@0\n    displayName: CodeQL Initialize\n\n  - script: eng\\common\\cibuild.cmd\n      -configuration $(_BuildConfig)\n      -prepareMachine\n      /p:Test=false\n    displayName: Windows Build\n\n  - task: CodeQL3000Finalize@0\n    displayName: CodeQL Finalize\n"
  },
  {
    "path": "azure-pipelines-pr.yml",
    "content": "variables:\n  - name: Build.Repository.Clean\n    value: true\n  - name: _TeamName\n    value: AspNetCore\n  - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE\n    value: true\n  - name: _PublishUsingPipelines\n    value: true\n  - name: _HelixType\n    value: build/product\n  - name: _HelixSource\n    value: pr/dotnet/HttpRepl/$(Build.SourceBranch)\n\nresources:\n  containers:\n  - container: LinuxContainer\n    image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-14.04-cross-0cd4667-20170319080304\n    options: --init # This ensures all the stray defunct processes are reaped.\n\npr:\n  branches:\n    include:\n    - \"*\"\n  paths:\n    include:\n    - /\n    exclude:\n    - CONTRIBUTING.md\n    - README.md\n    - SECURITY.md\n\nstages:\n- stage: build\n  displayName: Build\n  jobs:\n  - template: /eng/common/templates/jobs/jobs.yml\n    parameters:\n      enablePublishBuildArtifacts: true\n      testResultsFormat: xunit\n      enableTelemetry: true\n      helixRepo: dotnet/HttpRepl\n      jobs:\n      - job: Windows\n        pool:\n          name: NetCore-Public\n          demands: ImageOverride -equals windows.vs2022.amd64.open\n        variables:\n        - name: _HelixBuildConfig\n          value: $(_BuildConfig)\n        strategy:\n          matrix:\n            Debug:\n              _BuildConfig: Debug\n              _SignType: test\n              _BuildArgs: /p:DotNetSignType=$(_SignType) /p:TeamName=$(_TeamName)\n            Release:\n              _BuildConfig: Release\n              _SignType: test\n              _BuildArgs: /p:DotNetSignType=$(_SignType) /p:TeamName=$(_TeamName)\n        steps:\n        - checkout: self\n          clean: true\n        - task: NuGetCommand@2\n          displayName: 'Clear NuGet caches'\n          condition: succeeded()\n          inputs:\n            command: custom\n            arguments: 'locals all -clear'\n        - script: eng\\common\\cibuild.cmd\n            -configuration $(_BuildConfig)\n            -prepareMachine\n            -integrationTest\n            $(_BuildArgs)\n            /p:DotNetPublishUsingPipelines=$(_PublishUsingPipelines)\n          name: Build\n          displayName: Build\n          condition: succeeded()\n        - task: PublishBuildArtifacts@1\n          displayName: Publish Packages\n          condition: and(eq(variables['system.pullrequest.isfork'], false), eq(variables['_BuildConfig'], 'Release'))\n          continueOnError: true\n          inputs:\n            artifactName: Packages_$(Agent.Os)_$(Agent.JobName)\n            parallel: true\n            pathtoPublish: '$(Build.SourcesDirectory)/artifacts/packages/$(_BuildConfig)'\n            publishLocation: Container\n\n      - job: macOS\n        pool:\n          vmImage: macOS-latest\n        strategy:\n          matrix:\n            debug:\n              _BuildConfig: Debug\n            release:\n              _BuildConfig: Release\n        variables:\n        - name: _HelixBuildConfig\n          value: $(_BuildConfig)\n        steps:\n        - checkout: self\n          clean: true\n        - script: eng/common/cibuild.sh\n            --configuration $(_BuildConfig)\n            --prepareMachine\n            --integrationTest\n          name: Build\n          displayName: Build\n          condition: succeeded()\n\n      - job: Linux\n        pool:\n          vmImage: ubuntu-20.04\n          container: LinuxContainer\n        strategy:\n          matrix:\n            debug:\n              _BuildConfig: Debug\n            release:\n              _BuildConfig: Release\n        variables:\n        - name: _HelixBuildConfig\n          value: $(_BuildConfig)\n        steps:\n        - checkout: self\n          clean: true\n        - script: eng/common/cibuild.sh\n            --configuration $(_BuildConfig)\n            --prepareMachine\n            --integrationTest\n          name: Build\n          displayName: Build\n          condition: succeeded()\n"
  },
  {
    "path": "azure-pipelines.yml",
    "content": "variables:\n- template: /eng/common/templates-official/variables/pool-providers.yml@self\n- name: Build.Repository.Clean\n  value: true\n- name: _TeamName\n  value: AspNetCore\n- name: TeamName\n  value: AspNetCore\n- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE\n  value: true\n- name: _PublishUsingPipelines\n  value: true\n- name: _HelixType\n  value: build/product\n- name: _HelixSource\n  value: official/dotnet/HttpRepl/$(Build.SourceBranch)\n- name: _BuildConfig\n  value: Release\n- name: _SignType\n  value: real\n- name: _BuildArgs\n  value: /p:DotNetSignType=$(_SignType) /p:TeamName=$(_TeamName) /p:OfficialBuildId=$(Build.BuildNumber)\n- name: _HelixBuildConfig\n  value: $(_BuildConfig)\nresources:\n  repositories:\n  - repository: MicroBuildTemplate\n    type: git\n    name: 1ESPipelineTemplates/MicroBuildTemplate\n    ref: refs/tags/release\ntrigger:\n  branches:\n    include:\n    - main\n    - release/*\n  paths:\n    include:\n    - /\n    exclude:\n    - CONTRIBUTING.md\n    - README.md\n    - SECURITY.md\nextends:\n  template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate\n  parameters:\n    sdl:\n      sourceAnalysisPool:\n        name: $(DncEngInternalBuildPool)\n        image: 1es-windows-2022\n        os: windows\n      codeSignValidation:\n        # We make copies of our pre-signed binaries to the output directory, but we do not ship those. The signed ones\n        # are in the packages folder and pass CSV without issue. We only ship the signed packages, not any individual binaries\n        additionalTargetsGlobPattern: -|**\\bin\\**\n      policheck:\n        enabled: true\n      tsa:\n        enabled: true\n        configFile: '$(Build.SourcesDirectory)\\.config\\tsaoptions.json'\n    customBuildTags:\n    - ES365AIMigrationTooling\n    stages:\n    - stage: build\n      displayName: Build\n      jobs:\n      - template: /eng/common/templates-official/jobs/jobs.yml@self\n        parameters:\n          artifacts:\n            publish:\n              artifacts: true\n          enablePublishBuildArtifacts: true\n          testResultsFormat: xunit\n          enableTelemetry: true\n          helixRepo: dotnet/HttpRepl\n          enableMicrobuild: true\n          jobs:\n          - job: Windows\n            pool:\n              name: $(DncEngInternalBuildPool)\n              image: 1es-windows-2022\n              os: windows\n            steps:\n            - checkout: self\n              clean: true\n            - task: NuGetCommand@2\n              displayName: 'Clear NuGet caches'\n              condition: succeeded()\n              inputs:\n                command: custom\n                arguments: 'locals all -clear'\n            - script: eng\\common\\cibuild.cmd -configuration $(_BuildConfig) -prepareMachine -integrationTest $(_BuildArgs) /p:DotNetPublishUsingPipelines=$(_PublishUsingPipelines)\n              name: Build\n              displayName: Build\n              condition: succeeded()\n"
  },
  {
    "path": "build/analyzers/rulesets/Default.ruleset",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RuleSet Name=\"Common diagnostic rules to run during build for all Web Tools projects\" ToolsVersion=\"15.0\">\n  <!--\n    Note: Don't edit/save this file using VS, since it would remove all comments.\n  -->\n  <Include Path=\"sdl7.0.ruleset\" Action=\"Default\" />\n  <Rules AnalyzerId=\"Microsoft.CodeAnalysis.Analyzers\" RuleNamespace=\"Microsoft.CodeAnalysis.Analyzers\">\n    <Rule Id=\"RS1001\" Action=\"None\" />                        <!-- All RS analizers here are specific to Analyzer authoring. -->\n    <Rule Id=\"RS1004\" Action=\"None\" />\n    <Rule Id=\"RS1009\" Action=\"None\" />\n    <Rule Id=\"RS1010\" Action=\"None\" />\n    <Rule Id=\"RS1011\" Action=\"None\" />\n    <Rule Id=\"RS1016\" Action=\"None\" />\n    <Rule Id=\"RS1017\" Action=\"None\" />\n    <Rule Id=\"RS1018\" Action=\"None\" />\n    <Rule Id=\"RS1019\" Action=\"None\" />\n    <Rule Id=\"RS1021\" Action=\"None\" />\n  </Rules>\n  <Rules AnalyzerId=\"Microsoft.CodeAnalysis.CSharp\" RuleNamespace=\"Microsoft.CodeAnalysis.CSharp\">\n    <Rule Id=\"AD0001\" Action=\"None\" />                        <!-- Analyzer failure. -->\n  </Rules>\n  <Rules AnalyzerId=\"Microsoft.CodeQuality.Analyzers\" RuleNamespace=\"Microsoft.CodeQuality.Analyzers\">\n    <Rule Id=\"CA1000\" Action=\"Hidden\" />                      <!-- Do not declare static members on generic types. -->\n    <Rule Id=\"CA1001\" Action=\"Error\" />                       <!-- Types that own disposable fields should be disposable. -->\n    <Rule Id=\"CA1002\" Action=\"Info\" />                        <!-- Do not expose generic lists. -->\n    <Rule Id=\"CA1003\" Action=\"Warning\" />                     <!-- Use generic event handler instances. -->\n    <Rule Id=\"CA1004\" Action=\"Info\" />                        <!-- Generic methods should provide type parameter. -->\n    <Rule Id=\"CA1005\" Action=\"Info\" />                        <!-- Avoid excessive parameters on generic types. -->\n    <Rule Id=\"CA1007\" Action=\"Warning\" />                     <!-- Use generics where appropriate. An externally visible method contains a reference parameter of type System.Object. -->\n    <Rule Id=\"CA1008\" Action=\"Warning\" />                     <!-- Enums should have zero value. -->\n    <Rule Id=\"CA1010\" Action=\"Info\" />                        <!-- Collections should implement generic interface. -->\n    <Rule Id=\"CA1011\" Action=\"Warning\" />                     <!-- Consider passing base types as parameters. A method declaration includes a formal parameter that is a derived type, and the method calls only members of the base type of the parameter. -->\n    <Rule Id=\"CA1012\" Action=\"Warning\" />                     <!-- Abstract types should not have constructors. -->\n    <Rule Id=\"CA1013\" Action=\"Warning\" />                     <!-- Overload operator equals on overloading add and subtract. -->\n    <Rule Id=\"CA1019\" Action=\"Warning\" />                     <!-- Define accessors for attribute arguments. -->\n    <Rule Id=\"CA1023\" Action=\"Warning\" />                     <!-- Indexers should not be multidimensional. -->\n    <Rule Id=\"CA1026\" Action=\"Info\" />                        <!-- Default parameters should not be used. An externally visible type contains an externally visible method that uses a default parameter. -->\n    <Rule Id=\"CA1027\" Action=\"Info\" />                        <!-- Mark enums with FlagsAttribute. -->\n    <Rule Id=\"CA1034\" Action=\"Info\" />                        <!-- Nested types should not be visible. -->\n    <Rule Id=\"CA1035\" Action=\"Warning\" />                     <!-- ICollection implementations have strongly typed members. A public or protected type implements System.Collections.ICollection but does not provide a strongly typed method for ICollection.CopyTo. -->\n    <Rule Id=\"CA1038\" Action=\"Warning\" />                     <!-- Enumerators should be strongly typed. A public or protected type implements System.Collections.IEnumerator but does not provide a strongly typed version of the IEnumerator.Current property. -->\n    <Rule Id=\"CA1039\" Action=\"Warning\" />                     <!-- Lists are strongly typed. -->\n    <Rule Id=\"CA1041\" Action=\"Info\" />                        <!-- Provide ObsoleteAttribute message. -->\n    <Rule Id=\"CA1045\" Action=\"Info\" />                        <!-- Do not pass types by reference. -->\n    <Rule Id=\"CA1047\" Action=\"Error\" />                       <!-- Do not declare protected members in sealed types. -->\n    <Rule Id=\"CA1048\" Action=\"Error\" />                       <!-- Do not declare virtual members in sealed types. -->\n    <Rule Id=\"CA1050\" Action=\"Error\" />                       <!-- Declare types in namespaces. -->\n    <Rule Id=\"CA1052\" Action=\"Info\" />                        <!-- Static holder types should be sealed. -->\n    <Rule Id=\"CA1053\" Action=\"Info\" />                        <!-- Static holder types should not have constructors. -->\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=\"CA1057\" Action=\"None\" />                        <!-- String URI overloads call System.Uri overloads. -->\n    <Rule Id=\"CA1058\" Action=\"Info\" />                        <!-- Types should not extend certain base types (non-generic old collections). -->\n    <Rule Id=\"CA1063\" Action=\"None\" />                        <!-- The System.IDisposable interface is not implemented correctly. Note: Warning when https://github.com/dotnet/roslyn-analyzers/issues/1432 is fixed. -->\n    <Rule Id=\"CA1304\" Action=\"Warning\" />                     <!-- Specify CultureInfo. -->\n    <Rule Id=\"CA1710\" Action=\"None\" />                        <!-- Identifiers should have correct suffix. Attribute, EventArgs etc. -->\n    <Rule Id=\"CA1720\" Action=\"None\" />                        <!-- Identifiers should not contain type names. -->\n    <Rule Id=\"CA1801\" Action=\"Info\" />                        <!-- A method signature includes a parameter that is not used in the method body. -->\n    <Rule Id=\"CA1802\" Action=\"Info\" />                        <!-- Use Literals Where Appropriate. -->\n    <Rule Id=\"CA1806\" Action=\"Info\" />                        <!-- Do not ignore method results. COM and IVs -->\n    <Rule Id=\"CA1822\" Action=\"Info\" />                        <!-- Mark members as static. It changed incorrectly to complain about internal types too. TODO: make it warning later and followup with changes. -->\n    <Rule Id=\"CA2007\" Action=\"None\" />                        <!-- Alway use ConfigureAwait -->\n  </Rules>\n  <Rules AnalyzerId=\"Microsoft.CodeQuality.CSharp.Analyzers\" RuleNamespace=\"Microsoft.CodeQuality.CSharp.Analyzers\">\n    <Rule Id=\"Async001\" Action=\"Warning\" />                   <!-- Avoid async void. -->\n    <Rule Id=\"Async002\" Action=\"Warning\" />                   <!-- Async method should end with Async. -->\n    <Rule Id=\"Async003\" Action=\"Warning\" />                   <!-- Don't Pass Async Lambdas as Void Returning Delegate Types. -->\n    <Rule Id=\"Async004\" Action=\"Warning\" />                   <!-- Don't Store Async Lambdas as Void Returning Delegate Types. -->\n    <Rule Id=\"Async005\" Action=\"Info\" />                      <!-- Propagate cancellation token when possible. -->\n    <Rule Id=\"CA1001\" Action=\"Error\" />                       <!-- Types that own disposable fields should be disposable. -->\n    <Rule Id=\"CA1003\" Action=\"Warning\" />                     <!-- Use generic event handler instances. -->\n    <Rule Id=\"CA1019\" Action=\"Warning\" />                     <!-- Define accessors for attribute arguments. -->\n    <Rule Id=\"CA1500\" Action=\"Info\" />                        <!-- Variable names should not match field names -->\n  </Rules>\n  <Rules AnalyzerId=\"Microsoft.Composition.Analyzers\" RuleNamespace=\"Microsoft.Composition.Analyzers\">\n    <Rule Id=\"RS0006\" Action=\"None\" />                        <!-- Do not mix attributes from different versions of MEF. -->\n  </Rules>\n  <Rules AnalyzerId=\"Microsoft.NetCore.Analyzers\" RuleNamespace=\"Microsoft.NetCore.Analyzers\">\n    <Rule Id=\"CA1305\" Action=\"None\" />                        <!-- A method or constructor calls one or more members that have overloads that accept a System.IFormatProvider parameter. -->\n    <Rule Id=\"CA1307\" Action=\"Warning\" />                     <!-- A string comparison operation uses a method overload that does not set a StringComparison parameter. -->\n    <Rule Id=\"CA1308\" Action=\"Warning\" />                     <!-- Normalize strings to uppercase -->\n  </Rules>\n  <Rules AnalyzerId=\"Microsoft.VisualStudio.Threading.Analyzers\" RuleNamespace=\"Microsoft.VisualStudio.Threading.Analyzers\">\n    <Rule Id=\"VSTHRD010\" Action=\"None\" />                     <!-- Visual Studio service should be used on main thread explicitly. -->\n    <Rule Id=\"VSTHRD103\" Action=\"None\" />                     <!-- Call async methods when in an async method.-->\n    <Rule Id=\"VSTHRD108\" Action=\"None\" />                     <!-- Thread affinity checks should be unconditional. -->\n    <Rule Id=\"VSTHRD200\" Action=\"None\" />                     <!-- Naming styles                              Task Open()                                         Task OpenAsync()                       -->\n  </Rules>\n  <Rules AnalyzerId=\"Roslyn.Diagnostics.Analyzers\" RuleNamespace=\"Roslyn.Diagnostics.Analyzers\">\n    <Rule Id=\"RS0006\" Action=\"None\" />                        <!-- Do not mix attributes from different versions of MEF. -->\n  </Rules>\n  <Rules AnalyzerId=\"System.Runtime.Analyzers\" RuleNamespace=\"System.Runtime.Analyzers\">\n    <Rule Id=\"CA1305\" Action=\"None\" />                        <!-- A method or constructor calls one or more members that have overloads that accept a System.IFormatProvider parameter. -->\n    <Rule Id=\"CA1307\" Action=\"Warning\" />                     <!-- A string comparison operation uses a method overload that does not set a StringComparison parameter. -->\n    <Rule Id=\"CA1308\" Action=\"Warning\" />                     <!-- Normalize strings to uppercase -->\n  </Rules>\n</RuleSet>\n"
  },
  {
    "path": "build/analyzers/rulesets/Sdl7.0.ruleset",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RuleSet Name=\"SDL 7.0\" Description=\"SDL 7.0-prescribed required and recommended checks.\" ToolsVersion=\"11.0\">\n  <Rules AnalyzerId=\"Microsoft.Analyzers.ManagedCodeAnalysis\" RuleNamespace=\"Microsoft.Rules.Managed\">\n     <Rule Id=\"CA2100\" Action=\"Error\" />\n     <Rule Id=\"CA1304\" Action=\"Warning\" />\n     <Rule Id=\"CA1305\" Action=\"Warning\" />\n     <Rule Id=\"CA1307\" Action=\"Warning\" />\n     <Rule Id=\"CA1309\" Action=\"Warning\" />\n     <Rule Id=\"CA2101\" Action=\"Warning\" />\n     <Rule Id=\"CA1401\" Action=\"Warning\" />\n     <Rule Id=\"CA2001\" Action=\"Warning\" />\n     <Rule Id=\"CA2102\" Action=\"Warning\" />\n     <Rule Id=\"CA2103\" Action=\"Warning\" />\n     <Rule Id=\"CA2104\" Action=\"Warning\" />\n     <Rule Id=\"CA2105\" Action=\"Warning\" />\n     <Rule Id=\"CA2106\" Action=\"Error\" />\n     <Rule Id=\"CA2107\" Action=\"Warning\" />\n     <Rule Id=\"CA2108\" Action=\"Warning\" />\n     <Rule Id=\"CA2109\" Action=\"Warning\" />\n     <Rule Id=\"CA2111\" Action=\"Error\" />\n     <Rule Id=\"CA2112\" Action=\"Warning\" />\n     <Rule Id=\"CA2114\" Action=\"Warning\" />\n     <Rule Id=\"CA2115\" Action=\"Warning\" />\n     <Rule Id=\"CA2116\" Action=\"Warning\" />\n     <Rule Id=\"CA2117\" Action=\"Error\" />\n     <Rule Id=\"CA2118\" Action=\"Error\" />\n     <Rule Id=\"CA2119\" Action=\"Error\" />\n     <Rule Id=\"CA2120\" Action=\"Error\" />\n     <Rule Id=\"CA2121\" Action=\"Warning\" />\n     <Rule Id=\"CA2122\" Action=\"Warning\" />\n     <Rule Id=\"CA2124\" Action=\"Error\" />\n     <Rule Id=\"CA2126\" Action=\"Error\" />\n     <Rule Id=\"CA2123\" Action=\"Error\" />\n     <Rule Id=\"CA2130\" Action=\"Error\" />\n     <Rule Id=\"CA2131\" Action=\"Error\" />\n     <Rule Id=\"CA2132\" Action=\"Error\" />\n     <Rule Id=\"CA2133\" Action=\"Error\" />\n     <Rule Id=\"CA2134\" Action=\"Error\" />\n     <Rule Id=\"CA2135\" Action=\"Error\" />\n     <Rule Id=\"CA2136\" Action=\"Error\" />\n     <Rule Id=\"CA2137\" Action=\"Error\" />\n     <Rule Id=\"CA2138\" Action=\"Error\" />\n     <Rule Id=\"CA2139\" Action=\"Error\" />\n     <Rule Id=\"CA2140\" Action=\"Error\" />\n     <Rule Id=\"CA2141\" Action=\"Error\" />\n     <Rule Id=\"CA2142\" Action=\"Error\" />\n     <Rule Id=\"CA2143\" Action=\"Error\" />\n     <Rule Id=\"CA2144\" Action=\"Error\" />\n     <Rule Id=\"CA2145\" Action=\"Error\" />\n     <Rule Id=\"CA2146\" Action=\"Error\" />\n     <Rule Id=\"CA2147\" Action=\"Error\" />\n     <Rule Id=\"CA2149\" Action=\"Error\" />\n     <Rule Id=\"CA2151\" Action=\"Error\" />\n     <Rule Id=\"CA5122\" Action=\"Error\" />\n  </Rules>\n</RuleSet>\n"
  },
  {
    "path": "build.cmd",
    "content": "@echo off\npowershell -ExecutionPolicy ByPass -NoProfile -command \"& \"\"\"%~dp0eng\\common\\Build.ps1\"\"\" -build -restore -pack -test %*\"\nexit /b %ErrorLevel%"
  },
  {
    "path": "build.sh",
    "content": "#!/usr/bin/env bash\n\nsource=\"${BASH_SOURCE[0]}\"\n\n# resolve $SOURCE until the file is no longer a symlink\nwhile [[ -h $source ]]; do\n  scriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n  source=\"$(readlink \"$source\")\"\n\n  # if $source was a relative symlink, we need to resolve it relative to the path where the\n  # symlink file was located\n  [[ $source != /* ]] && source=\"$scriptroot/$source\"\ndone\n\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\"$scriptroot/eng/common/build.sh\" --pack --build --restore --test $@"
  },
  {
    "path": "eng/Build.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <!-- Specify the solutions to build. Add all new solutions/projects here as necessary or the main build won't build them! -->\n  <ItemGroup>\n    <ProjectToBuild Include=\"$(MSBuildThisFileDirectory)..\\HttpRepl.sln\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "eng/Signing.props",
    "content": "<Project>\n  <!--\n    These are third party libraries that we use in this repo. We need to sign them even if they\n    are already signed. However, they must be signed with a 3rd party certificate.\n  -->\n  <ItemGroup>\n    <FileSignInfo Include=\"Newtonsoft.Json.dll\" CertificateName=\"3PartySHA2\" />\n    <FileSignInfo Include=\"Newtonsoft.Json.Bson.dll\" CertificateName=\"3PartySHA2\" />\n    <FileSignInfo Include=\"SharpYaml.dll\" CertificateName=\"3PartySHA2\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "eng/Version.Details.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Dependencies>\n  <ProductDependencies>\n  </ProductDependencies>\n  <ToolsetDependencies>\n    <Dependency Name=\"Microsoft.DotNet.Arcade.Sdk\" Version=\"10.0.0-beta.25056.1\">\n      <Uri>https://github.com/dotnet/arcade</Uri>\n      <Sha>e58820063a8754d418518bce69ca2df0e3b4ac25</Sha>\n    </Dependency>\n  </ToolsetDependencies>\n</Dependencies>\n"
  },
  {
    "path": "eng/Versions.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <!-- Opt out of certain Arcade features -->\n  <PropertyGroup>\n    <UsingToolXliff>false</UsingToolXliff>\n  </PropertyGroup>\n  <PropertyGroup>\n    <VersionPrefix>8.1.0</VersionPrefix>\n    <PreReleaseVersionLabel>preview</PreReleaseVersionLabel>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "eng/common/BuildConfiguration/build-configuration.json",
    "content": "{\n  \"RetryCountLimit\": 1,\n  \"RetryByAnyError\": false\n}\n"
  },
  {
    "path": "eng/common/CIBuild.cmd",
    "content": "@echo off\npowershell -ExecutionPolicy ByPass -NoProfile -command \"& \"\"\"%~dp0Build.ps1\"\"\" -restore -build -test -sign -pack -publish -ci %*\""
  },
  {
    "path": "eng/common/PSScriptAnalyzerSettings.psd1",
    "content": "@{\n    IncludeRules=@('PSAvoidUsingCmdletAliases',\n                   'PSAvoidUsingWMICmdlet',\n                   'PSAvoidUsingPositionalParameters',\n                   'PSAvoidUsingInvokeExpression',\n                   'PSUseDeclaredVarsMoreThanAssignments',\n                   'PSUseCmdletCorrectly',\n                   'PSStandardDSCFunctionsInResource',\n                   'PSUseIdenticalMandatoryParametersForDSC',\n                   'PSUseIdenticalParametersForDSC')\n}"
  },
  {
    "path": "eng/common/README.md",
    "content": "# Don't touch this folder\n\n                uuuuuuuuuuuuuuuuuuuu\n              u\" uuuuuuuuuuuuuuuuuu \"u\n            u\" u$$$$$$$$$$$$$$$$$$$$u \"u\n          u\" u$$$$$$$$$$$$$$$$$$$$$$$$u \"u\n        u\" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$u \"u\n      u\" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u \"u\n    u\" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u \"u\n    $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $\n    $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $\n    $ $$$\" ... \"$...  ...$\" ... \"$$$  ... \"$$$ $\n    $ $$$u `\"$$$$$$$  $$$  $$$$$  $$  $$$  $$$ $\n    $ $$$$$$uu \"$$$$  $$$  $$$$$  $$  \"\"\" u$$$ $\n    $ $$$\"\"$$$  $$$$  $$$u \"$$$\" u$$  $$$$$$$$ $\n    $ $$$$....,$$$$$..$$$$$....,$$$$..$$$$$$$$ $\n    $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $\n    \"u \"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\" u\"\n      \"u \"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\" u\"\n        \"u \"$$$$$$$$$$$$$$$$$$$$$$$$$$$$\" u\"\n          \"u \"$$$$$$$$$$$$$$$$$$$$$$$$\" u\"\n            \"u \"$$$$$$$$$$$$$$$$$$$$\" u\"\n              \"u \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" u\"\n                \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\n!!! Changes made in this directory are subject to being overwritten by automation !!!\n\nThe files in this directory are shared by all Arcade repos and managed by automation. If you need to make changes to these files, open an issue or submit a pull request to https://github.com/dotnet/arcade first.\n"
  },
  {
    "path": "eng/common/SetupNugetSources.ps1",
    "content": "# This script adds internal feeds required to build commits that depend on internal package sources. For instance,\n# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables\n# disabled internal Maestro (darc-int*) feeds.\n#\n# Optionally, this script also adds a credential entry for each of the internal feeds if supplied.\n#\n# See example call for this script below.\n#\n#  - task: PowerShell@2\n#    displayName: Setup Private Feeds Credentials\n#    condition: eq(variables['Agent.OS'], 'Windows_NT')\n#    inputs:\n#      filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1\n#      arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token\n#    env:\n#      Token: $(dn-bot-dnceng-artifact-feeds-rw)\n#\n# Note that the NuGetAuthenticate task should be called after SetupNugetSources.\n# This ensures that:\n# - Appropriate creds are set for the added internal feeds (if not supplied to the scrupt)\n# - The credential provider is installed.\n#\n# This logic is also abstracted into enable-internal-sources.yml.\n\n[CmdletBinding()]\nparam (\n    [Parameter(Mandatory = $true)][string]$ConfigFile,\n    $Password\n)\n\n$ErrorActionPreference = \"Stop\"\nSet-StrictMode -Version 2.0\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n. $PSScriptRoot\\tools.ps1\n\n# Add source entry to PackageSources\nfunction AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) {\n    $packageSource = $sources.SelectSingleNode(\"add[@key='$SourceName']\")\n    \n    if ($packageSource -eq $null)\n    {\n        $packageSource = $doc.CreateElement(\"add\")\n        $packageSource.SetAttribute(\"key\", $SourceName)\n        $packageSource.SetAttribute(\"value\", $SourceEndPoint)\n        $sources.AppendChild($packageSource) | Out-Null\n    }\n    else {\n        Write-Host \"Package source $SourceName already present.\"\n    }\n\n    AddCredential -Creds $creds -Source $SourceName -Username $Username -pwd $pwd\n}\n\n# Add a credential node for the specified source\nfunction AddCredential($creds, $source, $username, $pwd) {\n    # If no cred supplied, don't do anything.\n    if (!$pwd) {\n        return;\n    }\n\n    # Looks for credential configuration for the given SourceName. Create it if none is found.\n    $sourceElement = $creds.SelectSingleNode($Source)\n    if ($sourceElement -eq $null)\n    {\n        $sourceElement = $doc.CreateElement($Source)\n        $creds.AppendChild($sourceElement) | Out-Null\n    }\n\n    # Add the <Username> node to the credential if none is found.\n    $usernameElement = $sourceElement.SelectSingleNode(\"add[@key='Username']\")\n    if ($usernameElement -eq $null)\n    {\n        $usernameElement = $doc.CreateElement(\"add\")\n        $usernameElement.SetAttribute(\"key\", \"Username\")\n        $sourceElement.AppendChild($usernameElement) | Out-Null\n    }\n    $usernameElement.SetAttribute(\"value\", $Username)\n\n    # Add the <ClearTextPassword> to the credential if none is found.\n    # Add it as a clear text because there is no support for encrypted ones in non-windows .Net SDKs.\n    #   -> https://github.com/NuGet/Home/issues/5526\n    $passwordElement = $sourceElement.SelectSingleNode(\"add[@key='ClearTextPassword']\")\n    if ($passwordElement -eq $null)\n    {\n        $passwordElement = $doc.CreateElement(\"add\")\n        $passwordElement.SetAttribute(\"key\", \"ClearTextPassword\")\n        $sourceElement.AppendChild($passwordElement) | Out-Null\n    }\n    \n    $passwordElement.SetAttribute(\"value\", $pwd)\n}\n\nfunction InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $pwd) {\n    $maestroPrivateSources = $Sources.SelectNodes(\"add[contains(@key,'darc-int')]\")\n\n    Write-Host \"Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds.\"\n    \n    ForEach ($PackageSource in $maestroPrivateSources) {\n        Write-Host \"`tInserting credential for Maestro's feed:\" $PackageSource.Key\n        AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -pwd $pwd\n    }\n}\n\nfunction EnablePrivatePackageSources($DisabledPackageSources) {\n    $maestroPrivateSources = $DisabledPackageSources.SelectNodes(\"add[contains(@key,'darc-int')]\")\n    ForEach ($DisabledPackageSource in $maestroPrivateSources) {\n        Write-Host \"`tEnsuring private source '$($DisabledPackageSource.key)' is enabled by deleting it from disabledPackageSource\"\n        # Due to https://github.com/NuGet/Home/issues/10291, we must actually remove the disabled entries\n        $DisabledPackageSources.RemoveChild($DisabledPackageSource)\n    }\n}\n\nif (!(Test-Path $ConfigFile -PathType Leaf)) {\n  Write-PipelineTelemetryError -Category 'Build' -Message \"Eng/common/SetupNugetSources.ps1 returned a non-zero exit code. Couldn't find the NuGet config file: $ConfigFile\"\n  ExitWithExitCode 1\n}\n\n# Load NuGet.config\n$doc = New-Object System.Xml.XmlDocument\n$filename = (Get-Item $ConfigFile).FullName\n$doc.Load($filename)\n\n# Get reference to <PackageSources> or create one if none exist already\n$sources = $doc.DocumentElement.SelectSingleNode(\"packageSources\")\nif ($sources -eq $null) {\n    $sources = $doc.CreateElement(\"packageSources\")\n    $doc.DocumentElement.AppendChild($sources) | Out-Null\n}\n\n$creds = $null\nif ($Password) {\n    # Looks for a <PackageSourceCredentials> node. Create it if none is found.\n    $creds = $doc.DocumentElement.SelectSingleNode(\"packageSourceCredentials\")\n    if ($creds -eq $null) {\n        $creds = $doc.CreateElement(\"packageSourceCredentials\")\n        $doc.DocumentElement.AppendChild($creds) | Out-Null\n    }\n}\n\n# Check for disabledPackageSources; we'll enable any darc-int ones we find there\n$disabledSources = $doc.DocumentElement.SelectSingleNode(\"disabledPackageSources\")\nif ($disabledSources -ne $null) {\n    Write-Host \"Checking for any darc-int disabled package sources in the disabledPackageSources node\"\n    EnablePrivatePackageSources -DisabledPackageSources $disabledSources\n}\n\n$userName = \"dn-bot\"\n\n# Insert credential nodes for Maestro's private feeds\nInsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -pwd $Password\n\n# 3.1 uses a different feed url format so it's handled differently here\n$dotnet31Source = $sources.SelectSingleNode(\"add[@key='dotnet3.1']\")\nif ($dotnet31Source -ne $null) {\n    AddPackageSource -Sources $sources -SourceName \"dotnet3.1-internal\" -SourceEndPoint \"https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2\" -Creds $creds -Username $userName -pwd $Password\n    AddPackageSource -Sources $sources -SourceName \"dotnet3.1-internal-transport\" -SourceEndPoint \"https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2\" -Creds $creds -Username $userName -pwd $Password\n}\n\n$dotnetVersions = @('5','6','7','8','9')\n\nforeach ($dotnetVersion in $dotnetVersions) {\n    $feedPrefix = \"dotnet\" + $dotnetVersion;\n    $dotnetSource = $sources.SelectSingleNode(\"add[@key='$feedPrefix']\")\n    if ($dotnetSource -ne $null) {\n        AddPackageSource -Sources $sources -SourceName \"$feedPrefix-internal\" -SourceEndPoint \"https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2\" -Creds $creds -Username $userName -pwd $Password\n        AddPackageSource -Sources $sources -SourceName \"$feedPrefix-internal-transport\" -SourceEndPoint \"https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2\" -Creds $creds -Username $userName -pwd $Password\n    }\n}\n\n$doc.Save($filename)\n"
  },
  {
    "path": "eng/common/SetupNugetSources.sh",
    "content": "#!/usr/bin/env bash\n\n# This script adds internal feeds required to build commits that depend on internal package sources. For instance,\n# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables\n# disabled internal Maestro (darc-int*) feeds.\n# \n# Optionally, this script also adds a credential entry for each of the internal feeds if supplied.\n#\n# See example call for this script below.\n#\n#  - task: Bash@3\n#    displayName: Setup Internal Feeds\n#    inputs:\n#      filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh\n#      arguments: $(Build.SourcesDirectory)/NuGet.config\n#    condition: ne(variables['Agent.OS'], 'Windows_NT')\n#  - task: NuGetAuthenticate@1\n#\n# Note that the NuGetAuthenticate task should be called after SetupNugetSources.\n# This ensures that:\n# - Appropriate creds are set for the added internal feeds (if not supplied to the scrupt)\n# - The credential provider is installed.\n#\n# This logic is also abstracted into enable-internal-sources.yml.\n\nConfigFile=$1\nCredToken=$2\nNL='\\n'\nTB='    '\n\nsource=\"${BASH_SOURCE[0]}\"\n\n# resolve $source until the file is no longer a symlink\nwhile [[ -h \"$source\" ]]; do\n  scriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n  source=\"$(readlink \"$source\")\"\n  # if $source was a relative symlink, we need to resolve it relative to the path where the\n  # symlink file was located\n  [[ $source != /* ]] && source=\"$scriptroot/$source\"\ndone\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\n. \"$scriptroot/tools.sh\"\n\nif [ ! -f \"$ConfigFile\" ]; then\n    Write-PipelineTelemetryError -Category 'Build' \"Error: Eng/common/SetupNugetSources.sh returned a non-zero exit code. Couldn't find the NuGet config file: $ConfigFile\"\n    ExitWithExitCode 1\nfi\n\nif [[ `uname -s` == \"Darwin\" ]]; then\n    NL=$'\\\\\\n'\n    TB=''\nfi\n\n# Ensure there is a <packageSources>...</packageSources> section.\ngrep -i \"<packageSources>\" $ConfigFile\nif [ \"$?\" != \"0\" ]; then\n    echo \"Adding <packageSources>...</packageSources> section.\"\n    ConfigNodeHeader=\"<configuration>\"\n    PackageSourcesTemplate=\"${TB}<packageSources>${NL}${TB}</packageSources>\"\n\n    sed -i.bak \"s|$ConfigNodeHeader|$ConfigNodeHeader${NL}$PackageSourcesTemplate|\" $ConfigFile\nfi\n\n# Ensure there is a <packageSourceCredentials>...</packageSourceCredentials> section. \ngrep -i \"<packageSourceCredentials>\" $ConfigFile\nif [ \"$?\" != \"0\" ]; then\n    echo \"Adding <packageSourceCredentials>...</packageSourceCredentials> section.\"\n\n    PackageSourcesNodeFooter=\"</packageSources>\"\n    PackageSourceCredentialsTemplate=\"${TB}<packageSourceCredentials>${NL}${TB}</packageSourceCredentials>\"\n\n    sed -i.bak \"s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|\" $ConfigFile\nfi\n\nPackageSources=()\n\n# Ensure dotnet3.1-internal and dotnet3.1-internal-transport are in the packageSources if the public dotnet3.1 feeds are present\ngrep -i \"<add key=\\\"dotnet3.1\\\"\" $ConfigFile\nif [ \"$?\" == \"0\" ]; then\n    grep -i \"<add key=\\\"dotnet3.1-internal\\\"\" $ConfigFile\n    if [ \"$?\" != \"0\" ]; then\n        echo \"Adding dotnet3.1-internal to the packageSources.\"\n        PackageSourcesNodeFooter=\"</packageSources>\"\n        PackageSourceTemplate=\"${TB}<add key=\\\"dotnet3.1-internal\\\" value=\\\"https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2\\\" />\"\n\n        sed -i.bak \"s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|\" $ConfigFile\n    fi\n    PackageSources+=('dotnet3.1-internal')\n\n    grep -i \"<add key=\\\"dotnet3.1-internal-transport\\\">\" $ConfigFile\n    if [ \"$?\" != \"0\" ]; then\n        echo \"Adding dotnet3.1-internal-transport to the packageSources.\"\n        PackageSourcesNodeFooter=\"</packageSources>\"\n        PackageSourceTemplate=\"${TB}<add key=\\\"dotnet3.1-internal-transport\\\" value=\\\"https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2\\\" />\"\n\n        sed -i.bak \"s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|\" $ConfigFile\n    fi\n    PackageSources+=('dotnet3.1-internal-transport')\nfi\n\nDotNetVersions=('5' '6' '7' '8' '9')\n\nfor DotNetVersion in ${DotNetVersions[@]} ; do\n    FeedPrefix=\"dotnet${DotNetVersion}\";\n    grep -i \"<add key=\\\"$FeedPrefix\\\"\" $ConfigFile\n    if [ \"$?\" == \"0\" ]; then\n        grep -i \"<add key=\\\"$FeedPrefix-internal\\\"\" $ConfigFile\n        if [ \"$?\" != \"0\" ]; then\n            echo \"Adding $FeedPrefix-internal to the packageSources.\"\n            PackageSourcesNodeFooter=\"</packageSources>\"\n            PackageSourceTemplate=\"${TB}<add key=\\\"$FeedPrefix-internal\\\" value=\\\"https://pkgs.dev.azure.com/dnceng/internal/_packaging/$FeedPrefix-internal/nuget/v2\\\" />\"\n\n            sed -i.bak \"s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|\" $ConfigFile\n        fi\n        PackageSources+=(\"$FeedPrefix-internal\")\n\n        grep -i \"<add key=\\\"$FeedPrefix-internal-transport\\\">\" $ConfigFile\n        if [ \"$?\" != \"0\" ]; then\n            echo \"Adding $FeedPrefix-internal-transport to the packageSources.\"\n            PackageSourcesNodeFooter=\"</packageSources>\"\n            PackageSourceTemplate=\"${TB}<add key=\\\"$FeedPrefix-internal-transport\\\" value=\\\"https://pkgs.dev.azure.com/dnceng/internal/_packaging/$FeedPrefix-internal-transport/nuget/v2\\\" />\"\n\n            sed -i.bak \"s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|\" $ConfigFile\n        fi\n        PackageSources+=(\"$FeedPrefix-internal-transport\")\n    fi\ndone\n\n# I want things split line by line\nPrevIFS=$IFS\nIFS=$'\\n'\nPackageSources+=\"$IFS\"\nPackageSources+=$(grep -oh '\"darc-int-[^\"]*\"' $ConfigFile | tr -d '\"')\nIFS=$PrevIFS\n\nif [ \"$CredToken\" ]; then\n    for FeedName in ${PackageSources[@]} ; do\n        # Check if there is no existing credential for this FeedName\n        grep -i \"<$FeedName>\" $ConfigFile \n        if [ \"$?\" != \"0\" ]; then\n            echo \"Adding credentials for $FeedName.\"\n\n            PackageSourceCredentialsNodeFooter=\"</packageSourceCredentials>\"\n            NewCredential=\"${TB}${TB}<$FeedName>${NL}<add key=\\\"Username\\\" value=\\\"dn-bot\\\" />${NL}<add key=\\\"ClearTextPassword\\\" value=\\\"$CredToken\\\" />${NL}</$FeedName>\"\n\n            sed -i.bak \"s|$PackageSourceCredentialsNodeFooter|$NewCredential${NL}$PackageSourceCredentialsNodeFooter|\" $ConfigFile\n        fi\n    done\nfi\n\n# Re-enable any entries in disabledPackageSources where the feed name contains darc-int\ngrep -i \"<disabledPackageSources>\" $ConfigFile\nif [ \"$?\" == \"0\" ]; then\n    DisabledDarcIntSources=()\n    echo \"Re-enabling any disabled \\\"darc-int\\\" package sources in $ConfigFile\"\n    DisabledDarcIntSources+=$(grep -oh '\"darc-int-[^\"]*\" value=\"true\"' $ConfigFile  | tr -d '\"')\n    for DisabledSourceName in ${DisabledDarcIntSources[@]} ; do\n        if [[ $DisabledSourceName == darc-int* ]]\n            then\n                OldDisableValue=\"<add key=\\\"$DisabledSourceName\\\" value=\\\"true\\\" />\"\n                NewDisableValue=\"<!-- Reenabled for build : $DisabledSourceName -->\"\n                sed -i.bak \"s|$OldDisableValue|$NewDisableValue|\" $ConfigFile\n                echo \"Neutralized disablePackageSources entry for '$DisabledSourceName'\"\n        fi\n    done\nfi\n"
  },
  {
    "path": "eng/common/build.cmd",
    "content": "@echo off\npowershell -ExecutionPolicy ByPass -NoProfile -command \"& \"\"\"%~dp0build.ps1\"\"\" %*\"\nexit /b %ErrorLevel%\n"
  },
  {
    "path": "eng/common/build.ps1",
    "content": "[CmdletBinding(PositionalBinding=$false)]\nParam(\n  [string][Alias('c')]$configuration = \"Debug\",\n  [string]$platform = $null,\n  [string] $projects,\n  [string][Alias('v')]$verbosity = \"minimal\",\n  [string] $msbuildEngine = $null,\n  [bool] $warnAsError = $true,\n  [bool] $nodeReuse = $true,\n  [switch][Alias('r')]$restore,\n  [switch] $deployDeps,\n  [switch][Alias('b')]$build,\n  [switch] $rebuild,\n  [switch] $deploy,\n  [switch][Alias('t')]$test,\n  [switch] $integrationTest,\n  [switch] $performanceTest,\n  [switch] $sign,\n  [switch] $pack,\n  [switch] $publish,\n  [switch] $clean,\n  [switch][Alias('pb')]$productBuild,\n  [switch][Alias('bl')]$binaryLog,\n  [switch][Alias('nobl')]$excludeCIBinarylog,\n  [switch] $ci,\n  [switch] $prepareMachine,\n  [string] $runtimeSourceFeed = '',\n  [string] $runtimeSourceFeedKey = '',\n  [switch] $excludePrereleaseVS,\n  [switch] $nativeToolsOnMachine,\n  [switch] $help,\n  [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties\n)\n\n# Unset 'Platform' environment variable to avoid unwanted collision in InstallDotNetCore.targets file\n# some computer has this env var defined (e.g. Some HP)\nif($env:Platform) {\n  $env:Platform=\"\"  \n}\nfunction Print-Usage() {\n  Write-Host \"Common settings:\"\n  Write-Host \"  -configuration <value>  Build configuration: 'Debug' or 'Release' (short: -c)\"\n  Write-Host \"  -platform <value>       Platform configuration: 'x86', 'x64' or any valid Platform value to pass to msbuild\"\n  Write-Host \"  -verbosity <value>      Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)\"\n  Write-Host \"  -binaryLog              Output binary log (short: -bl)\"\n  Write-Host \"  -help                   Print help and exit\"\n  Write-Host \"\"\n\n  Write-Host \"Actions:\"\n  Write-Host \"  -restore                Restore dependencies (short: -r)\"\n  Write-Host \"  -build                  Build solution (short: -b)\"\n  Write-Host \"  -rebuild                Rebuild solution\"\n  Write-Host \"  -deploy                 Deploy built VSIXes\"\n  Write-Host \"  -deployDeps             Deploy dependencies (e.g. VSIXes for integration tests)\"\n  Write-Host \"  -test                   Run all unit tests in the solution (short: -t)\"\n  Write-Host \"  -integrationTest        Run all integration tests in the solution\"\n  Write-Host \"  -performanceTest        Run all performance tests in the solution\"\n  Write-Host \"  -pack                   Package build outputs into NuGet packages and Willow components\"\n  Write-Host \"  -sign                   Sign build outputs\"\n  Write-Host \"  -publish                Publish artifacts (e.g. symbols)\"\n  Write-Host \"  -clean                  Clean the solution\"\n  Write-Host \"  -productBuild           Build the solution in the way it will be built in the full .NET product (VMR) build (short: -pb)\"\n  Write-Host \"\"\n\n  Write-Host \"Advanced settings:\"\n  Write-Host \"  -projects <value>       Semi-colon delimited list of sln/proj's to build. Globbing is supported (*.sln)\"\n  Write-Host \"  -ci                     Set when running on CI server\"\n  Write-Host \"  -excludeCIBinarylog     Don't output binary log (short: -nobl)\"\n  Write-Host \"  -prepareMachine         Prepare machine for CI run, clean up processes after build\"\n  Write-Host \"  -warnAsError <value>    Sets warnaserror msbuild parameter ('true' or 'false')\"\n  Write-Host \"  -msbuildEngine <value>  Msbuild engine to use to run build ('dotnet', 'vs', or unspecified).\"\n  Write-Host \"  -excludePrereleaseVS    Set to exclude build engines in prerelease versions of Visual Studio\"\n  Write-Host \"  -nativeToolsOnMachine   Sets the native tools on machine environment variable (indicating that the script should use native tools on machine)\"\n  Write-Host \"\"\n\n  Write-Host \"Command line arguments not listed above are passed thru to msbuild.\"\n  Write-Host \"The above arguments can be shortened as much as to be unambiguous (e.g. -co for configuration, -t for test, etc.).\"\n}\n\n. $PSScriptRoot\\tools.ps1\n\nfunction InitializeCustomToolset {\n  if (-not $restore) {\n    return\n  }\n\n  $script = Join-Path $EngRoot 'restore-toolset.ps1'\n\n  if (Test-Path $script) {\n    . $script\n  }\n}\n\nfunction Build {\n  $toolsetBuildProj = InitializeToolset\n  InitializeCustomToolset\n\n  $bl = if ($binaryLog) { '/bl:' + (Join-Path $LogDir 'Build.binlog') } else { '' }\n  $platformArg = if ($platform) { \"/p:Platform=$platform\" } else { '' }\n\n  if ($projects) {\n    # Re-assign properties to a new variable because PowerShell doesn't let us append properties directly for unclear reasons.\n    # Explicitly set the type as string[] because otherwise PowerShell would make this char[] if $properties is empty.\n    [string[]] $msbuildArgs = $properties\n    \n    # Resolve relative project paths into full paths \n    $projects = ($projects.Split(';').ForEach({Resolve-Path $_}) -join ';')\n    \n    $msbuildArgs += \"/p:Projects=$projects\"\n    $properties = $msbuildArgs\n  }\n\n  MSBuild $toolsetBuildProj `\n    $bl `\n    $platformArg `\n    /p:Configuration=$configuration `\n    /p:RepoRoot=$RepoRoot `\n    /p:Restore=$restore `\n    /p:DeployDeps=$deployDeps `\n    /p:Build=$build `\n    /p:Rebuild=$rebuild `\n    /p:Deploy=$deploy `\n    /p:Test=$test `\n    /p:Pack=$pack `\n    /p:DotNetBuildRepo=$productBuild `\n    /p:IntegrationTest=$integrationTest `\n    /p:PerformanceTest=$performanceTest `\n    /p:Sign=$sign `\n    /p:Publish=$publish `\n    @properties\n}\n\ntry {\n  if ($clean) {\n    if (Test-Path $ArtifactsDir) {\n      Remove-Item -Recurse -Force $ArtifactsDir\n      Write-Host 'Artifacts directory deleted.'\n    }\n    exit 0\n  }\n\n  if ($help -or (($null -ne $properties) -and ($properties.Contains('/help') -or $properties.Contains('/?')))) {\n    Print-Usage\n    exit 0\n  }\n\n  if ($ci) {\n    if (-not $excludeCIBinarylog) {\n      $binaryLog = $true\n    }\n    $nodeReuse = $false\n  }\n\n  if ($nativeToolsOnMachine) {\n    $env:NativeToolsOnMachine = $true\n  }\n  if ($restore) {\n    InitializeNativeTools\n  }\n\n  Build\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_\n  ExitWithExitCode 1\n}\n\nExitWithExitCode 0\n"
  },
  {
    "path": "eng/common/build.sh",
    "content": "#!/usr/bin/env bash\n\n# Stop script if unbound variable found (use ${var:-} if intentional)\nset -u\n\n# Stop script if command returns non-zero exit code.\n# Prevents hidden errors caused by missing error code propagation.\nset -e\n\nusage()\n{\n  echo \"Common settings:\"\n  echo \"  --configuration <value>    Build configuration: 'Debug' or 'Release' (short: -c)\"\n  echo \"  --verbosity <value>        Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)\"\n  echo \"  --binaryLog                Create MSBuild binary log (short: -bl)\"\n  echo \"  --help                     Print help and exit (short: -h)\"\n  echo \"\"\n\n  echo \"Actions:\"\n  echo \"  --restore                  Restore dependencies (short: -r)\"\n  echo \"  --build                    Build solution (short: -b)\"\n  echo \"  --sourceBuild              Source-build the solution (short: -sb)\"\n  echo \"                             Will additionally trigger the following actions: --restore, --build, --pack\"\n  echo \"                             If --configuration is not set explicitly, will also set it to 'Release'\"\n  echo \"  --productBuild             Build the solution in the way it will be built in the full .NET product (VMR) build (short: -pb)\"\n  echo \"                             Will additionally trigger the following actions: --restore, --build, --pack\"\n  echo \"                             If --configuration is not set explicitly, will also set it to 'Release'\"\n  echo \"  --rebuild                  Rebuild solution\"\n  echo \"  --test                     Run all unit tests in the solution (short: -t)\"\n  echo \"  --integrationTest          Run all integration tests in the solution\"\n  echo \"  --performanceTest          Run all performance tests in the solution\"\n  echo \"  --pack                     Package build outputs into NuGet packages and Willow components\"\n  echo \"  --sign                     Sign build outputs\"\n  echo \"  --publish                  Publish artifacts (e.g. symbols)\"\n  echo \"  --clean                    Clean the solution\"\n  echo \"\"\n\n  echo \"Advanced settings:\"\n  echo \"  --projects <value>       Project or solution file(s) to build\"\n  echo \"  --ci                     Set when running on CI server\"\n  echo \"  --excludeCIBinarylog     Don't output binary log (short: -nobl)\"\n  echo \"  --prepareMachine         Prepare machine for CI run, clean up processes after build\"\n  echo \"  --nodeReuse <value>      Sets nodereuse msbuild parameter ('true' or 'false')\"\n  echo \"  --warnAsError <value>    Sets warnaserror msbuild parameter ('true' or 'false')\"\n  echo \"\"\n  echo \"Command line arguments not listed above are passed thru to msbuild.\"\n  echo \"Arguments can also be passed in with a single hyphen.\"\n}\n\nsource=\"${BASH_SOURCE[0]}\"\n\n# resolve $source until the file is no longer a symlink\nwhile [[ -h \"$source\" ]]; do\n  scriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n  source=\"$(readlink \"$source\")\"\n  # if $source was a relative symlink, we need to resolve it relative to the path where the\n  # symlink file was located\n  [[ $source != /* ]] && source=\"$scriptroot/$source\"\ndone\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\nrestore=false\nbuild=false\nsource_build=false\nproduct_build=false\nrebuild=false\ntest=false\nintegration_test=false\nperformance_test=false\npack=false\npublish=false\nsign=false\npublic=false\nci=false\nclean=false\n\nwarn_as_error=true\nnode_reuse=true\nbinary_log=false\nexclude_ci_binary_log=false\npipelines_log=false\n\nprojects=''\nconfiguration=''\nprepare_machine=false\nverbosity='minimal'\nruntime_source_feed=''\nruntime_source_feed_key=''\n\nproperties=''\nwhile [[ $# > 0 ]]; do\n  opt=\"$(echo \"${1/#--/-}\" | tr \"[:upper:]\" \"[:lower:]\")\"\n  case \"$opt\" in\n    -help|-h)\n      usage\n      exit 0\n      ;;\n    -clean)\n      clean=true\n      ;;\n    -configuration|-c)\n      configuration=$2\n      shift\n      ;;\n    -verbosity|-v)\n      verbosity=$2\n      shift\n      ;;\n    -binarylog|-bl)\n      binary_log=true\n      ;;\n    -excludecibinarylog|-nobl)\n      exclude_ci_binary_log=true\n      ;;\n    -pipelineslog|-pl)\n      pipelines_log=true\n      ;;\n    -restore|-r)\n      restore=true\n      ;;\n    -build|-b)\n      build=true\n      ;;\n    -rebuild)\n      rebuild=true\n      ;;\n    -pack)\n      pack=true\n      ;;\n    -sourcebuild|-sb)\n      build=true\n      source_build=true\n      product_build=true\n      restore=true\n      pack=true\n      ;;\n    -productBuild|-pb)\n      build=true\n      product_build=true\n      restore=true\n      pack=true\n      ;;\n    -test|-t)\n      test=true\n      ;;\n    -integrationtest)\n      integration_test=true\n      ;;\n    -performancetest)\n      performance_test=true\n      ;;\n    -sign)\n      sign=true\n      ;;\n    -publish)\n      publish=true\n      ;;\n    -preparemachine)\n      prepare_machine=true\n      ;;\n    -projects)\n      projects=$2\n      shift\n      ;;\n    -ci)\n      ci=true\n      ;;\n    -warnaserror)\n      warn_as_error=$2\n      shift\n      ;;\n    -nodereuse)\n      node_reuse=$2\n      shift\n      ;;\n    -runtimesourcefeed)\n      runtime_source_feed=$2\n      shift\n      ;;\n     -runtimesourcefeedkey)\n      runtime_source_feed_key=$2\n      shift\n      ;;\n    *)\n      properties=\"$properties $1\"\n      ;;\n  esac\n\n  shift\ndone\n\nif [[ -z \"$configuration\" ]]; then\n  if [[ \"$source_build\" = true ]]; then configuration=\"Release\"; else configuration=\"Debug\"; fi\nfi\n\nif [[ \"$ci\" == true ]]; then\n  pipelines_log=true\n  node_reuse=false\n  if [[ \"$exclude_ci_binary_log\" == false ]]; then\n    binary_log=true\n  fi\nfi\n\n. \"$scriptroot/tools.sh\"\n\nfunction InitializeCustomToolset {\n  local script=\"$eng_root/restore-toolset.sh\"\n\n  if [[ -a \"$script\" ]]; then\n    . \"$script\"\n  fi\n}\n\nfunction Build {\n  InitializeToolset\n  InitializeCustomToolset\n\n  if [[ ! -z \"$projects\" ]]; then\n    properties=\"$properties /p:Projects=$projects\"\n  fi\n\n  local bl=\"\"\n  if [[ \"$binary_log\" == true ]]; then\n    bl=\"/bl:\\\"$log_dir/Build.binlog\\\"\"\n  fi\n\n  MSBuild $_InitializeToolset \\\n    $bl \\\n    /p:Configuration=$configuration \\\n    /p:RepoRoot=\"$repo_root\" \\\n    /p:Restore=$restore \\\n    /p:Build=$build \\\n    /p:DotNetBuildRepo=$product_build \\\n    /p:DotNetBuildSourceOnly=$source_build \\\n    /p:Rebuild=$rebuild \\\n    /p:Test=$test \\\n    /p:Pack=$pack \\\n    /p:IntegrationTest=$integration_test \\\n    /p:PerformanceTest=$performance_test \\\n    /p:Sign=$sign \\\n    /p:Publish=$publish \\\n    $properties\n\n  ExitWithExitCode 0\n}\n\nif [[ \"$clean\" == true ]]; then\n  if [ -d \"$artifacts_dir\" ]; then\n    rm -rf $artifacts_dir\n    echo \"Artifacts directory deleted.\"\n  fi\n  exit 0\nfi\n\nif [[ \"$restore\" == true ]]; then\n  InitializeNativeTools\nfi\n\nBuild\n"
  },
  {
    "path": "eng/common/cibuild.sh",
    "content": "#!/usr/bin/env bash\n\nsource=\"${BASH_SOURCE[0]}\"\n\n# resolve $SOURCE until the file is no longer a symlink\nwhile [[ -h $source ]]; do\n  scriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n  source=\"$(readlink \"$source\")\"\n\n  # if $source was a relative symlink, we need to resolve it relative to the path where \n  # the symlink file was located\n  [[ $source != /* ]] && source=\"$scriptroot/$source\"\ndone\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\n. \"$scriptroot/build.sh\" --restore --build --test --pack --publish --ci $@"
  },
  {
    "path": "eng/common/core-templates/job/job.yml",
    "content": "parameters:\n# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job\n  cancelTimeoutInMinutes: ''\n  condition: ''\n  container: ''\n  continueOnError: false\n  dependsOn: ''\n  displayName: ''\n  pool: ''\n  steps: []\n  strategy: ''\n  timeoutInMinutes: ''\n  variables: []\n  workspace: ''\n  templateContext: {}\n\n# Job base template specific parameters\n  # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md\n  # publishing defaults\n  artifacts: ''\n  enableMicrobuild: false\n  enableMicrobuildForMacAndLinux: false\n  enablePublishBuildArtifacts: false\n  enablePublishBuildAssets: false\n  enablePublishTestResults: false\n  enablePublishUsingPipelines: false\n  enableBuildRetry: false\n  mergeTestResults: false\n  testRunTitle: ''\n  testResultsFormat: ''\n  name: ''\n  componentGovernanceSteps: []\n  preSteps: []\n  artifactPublishSteps: []\n  runAsPublic: false\n\n# 1es specific parameters\n  is1ESPipeline: ''\n\njobs:\n- job: ${{ parameters.name }}\n\n  ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}:\n    cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }}\n\n  ${{ if ne(parameters.condition, '') }}:\n    condition: ${{ parameters.condition }}\n\n  ${{ if ne(parameters.container, '') }}:\n    container: ${{ parameters.container }}\n\n  ${{ if ne(parameters.continueOnError, '') }}:\n    continueOnError: ${{ parameters.continueOnError }}\n\n  ${{ if ne(parameters.dependsOn, '') }}:\n    dependsOn: ${{ parameters.dependsOn }}\n\n  ${{ if ne(parameters.displayName, '') }}:\n    displayName: ${{ parameters.displayName }}\n\n  ${{ if ne(parameters.pool, '') }}:\n    pool: ${{ parameters.pool }}\n\n  ${{ if ne(parameters.strategy, '') }}:\n    strategy: ${{ parameters.strategy }}\n\n  ${{ if ne(parameters.timeoutInMinutes, '') }}:\n    timeoutInMinutes: ${{ parameters.timeoutInMinutes }}\n\n  ${{ if ne(parameters.templateContext, '') }}:\n    templateContext: ${{ parameters.templateContext }}\n\n  variables:\n  - ${{ if ne(parameters.enableTelemetry, 'false') }}:\n    - name: DOTNET_CLI_TELEMETRY_PROFILE\n      value: '$(Build.Repository.Uri)'\n  - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}:\n    - name: EnableRichCodeNavigation\n      value: 'true'\n  # Retry signature validation up to three times, waiting 2 seconds between attempts.\n  # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures\n  - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY\n    value: 3,2000\n  - ${{ each variable in parameters.variables }}:\n    # handle name-value variable syntax\n    # example:\n    # - name: [key]\n    #   value: [value]\n    - ${{ if ne(variable.name, '') }}:\n      - name: ${{ variable.name }}\n        value: ${{ variable.value }}\n\n    # handle variable groups\n    - ${{ if ne(variable.group, '') }}:\n      - group: ${{ variable.group }}\n\n    # handle template variable syntax\n    # example:\n    # - template: path/to/template.yml\n    #   parameters:\n    #     [key]: [value]\n    - ${{ if ne(variable.template, '') }}:\n      - template: ${{ variable.template }}\n        ${{ if ne(variable.parameters, '') }}:\n          parameters: ${{ variable.parameters }}\n\n    # handle key-value variable syntax.\n    # example:\n    # - [key]: [value]\n    - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}:\n      - ${{ each pair in variable }}:\n        - name: ${{ pair.key }}\n          value: ${{ pair.value }}\n\n  # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds\n  - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:\n    - group: DotNet-HelixApi-Access\n\n  ${{ if ne(parameters.workspace, '') }}:\n    workspace: ${{ parameters.workspace }}\n\n  steps:\n  - ${{ if eq(parameters.is1ESPipeline, '') }}:\n    - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error\n\n  - ${{ if ne(parameters.preSteps, '') }}:\n    - ${{ each preStep in parameters.preSteps }}:\n      - ${{ preStep }}\n\n  - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:\n    - template: /eng/common/core-templates/steps/install-microbuild.yml\n      parameters:\n        enableMicrobuild: ${{ parameters.enableMicrobuild }}\n        enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }}\n        continueOnError: ${{ parameters.continueOnError }}\n\n  - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}:\n    - task: NuGetAuthenticate@1\n\n  - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}:\n    - task: DownloadPipelineArtifact@2\n      inputs:\n        buildType: current\n        artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }}\n        targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }}\n        itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }}\n\n  - ${{ each step in parameters.steps }}:\n    - ${{ step }}\n\n  - ${{ if eq(parameters.enableRichCodeNavigation, true) }}:\n    - task: RichCodeNavIndexer@0\n      displayName: RichCodeNav Upload\n      inputs:\n        languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }}\n        environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'internal') }}\n        richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin\n        uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }}\n      continueOnError: true\n\n  - ${{ each step in parameters.componentGovernanceSteps }}:\n    - ${{ step }}\n\n  - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:\n    - template: /eng/common/core-templates/steps/cleanup-microbuild.yml\n      parameters:\n        enableMicrobuild: ${{ parameters.enableMicrobuild }}\n        enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }}\n        continueOnError: ${{ parameters.continueOnError }}\n\n  # Publish test results\n  - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}:\n    - task: PublishTestResults@2\n      displayName: Publish XUnit Test Results\n      inputs:\n        testResultsFormat: 'xUnit'\n        testResultsFiles: '*.xml'\n        searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'\n        testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit\n        mergeTestResults: ${{ parameters.mergeTestResults }}\n      continueOnError: true\n      condition: always()\n  - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}:\n    - task: PublishTestResults@2\n      displayName: Publish TRX Test Results\n      inputs:\n        testResultsFormat: 'VSTest'\n        testResultsFiles: '*.trx'\n        searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'\n        testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx\n        mergeTestResults: ${{ parameters.mergeTestResults }}\n      continueOnError: true\n      condition: always()\n\n  # gather artifacts\n  - ${{ if ne(parameters.artifacts.publish, '') }}:\n    - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:\n      - task: CopyFiles@2\n        displayName: Gather binaries for publish to artifacts\n        inputs:\n          SourceFolder: 'artifacts/bin'\n          Contents: '**'\n          TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin'\n      - task: CopyFiles@2\n        displayName: Gather packages for publish to artifacts\n        inputs:\n          SourceFolder: 'artifacts/packages'\n          Contents: '**'\n          TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages'\n    - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:\n      - task: CopyFiles@2\n        displayName: Gather logs for publish to artifacts\n        inputs:\n          SourceFolder: 'artifacts/log'\n          Contents: '**'\n          TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/log'\n        continueOnError: true\n        condition: always()\n      \n  - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:\n    - task: CopyFiles@2\n      displayName: Gather logs for publish to artifacts\n      inputs:\n        SourceFolder: 'artifacts/log/$(_BuildConfig)'\n        Contents: '**'\n        TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'\n      continueOnError: true\n      condition: always()\n  - ${{ if eq(parameters.enableBuildRetry, 'true') }}:\n    - task: CopyFiles@2\n      displayName: Gather buildconfiguration for build retry\n      inputs:\n        SourceFolder: '$(Build.SourcesDirectory)/eng/common/BuildConfiguration'\n        Contents: '**'\n        TargetFolder: '$(Build.ArtifactStagingDirectory)/eng/common/BuildConfiguration'\n      continueOnError: true\n      condition: always()\n  - ${{ each step in parameters.artifactPublishSteps }}:\n    - ${{ step }}\n"
  },
  {
    "path": "eng/common/core-templates/job/onelocbuild.yml",
    "content": "parameters:\n  # Optional: dependencies of the job\n  dependsOn: ''\n\n  # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool\n  pool: ''\n    \n  CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex\n  GithubPat: $(BotAccount-dotnet-bot-repo-PAT)\n\n  SourcesDirectory: $(Build.SourcesDirectory)\n  CreatePr: true\n  AutoCompletePr: false\n  ReusePr: true\n  UseLfLineEndings: true\n  UseCheckedInLocProjectJson: false\n  SkipLocProjectJsonGeneration: false\n  LanguageSet: VS_Main_Languages\n  LclSource: lclFilesInRepo\n  LclPackageId: ''\n  RepoType: gitHub\n  GitHubOrg: dotnet\n  MirrorRepo: ''\n  MirrorBranch: main\n  condition: ''\n  JobNameSuffix: ''\n  is1ESPipeline: ''\njobs:\n- job: OneLocBuild${{ parameters.JobNameSuffix }}\n  \n  dependsOn: ${{ parameters.dependsOn }}\n\n  displayName: OneLocBuild${{ parameters.JobNameSuffix }}\n\n  variables:\n    - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat\n    - name: _GenerateLocProjectArguments\n      value: -SourcesDirectory ${{ parameters.SourcesDirectory }}\n        -LanguageSet \"${{ parameters.LanguageSet }}\"\n        -CreateNeutralXlfs\n    - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}:\n      - name: _GenerateLocProjectArguments\n        value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson\n    - template: /eng/common/core-templates/variables/pool-providers.yml\n      parameters:\n        is1ESPipeline: ${{ parameters.is1ESPipeline }}\n\n  ${{ if ne(parameters.pool, '') }}:\n    pool: ${{ parameters.pool }}\n  ${{ if eq(parameters.pool, '') }}:\n    pool:\n      # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)\n      ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:\n        name: AzurePipelines-EO\n        image: 1ESPT-Windows2022\n        demands: Cmd\n        os: windows\n      # If it's not devdiv, it's dnceng\n      ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:\n        name: $(DncEngInternalBuildPool)\n        image: 1es-windows-2022\n        os: windows\n\n  steps:\n    - ${{ if eq(parameters.is1ESPipeline, '') }}:\n      - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error\n\n    - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}:\n      - task: Powershell@2\n        inputs:\n          filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1\n          arguments: $(_GenerateLocProjectArguments)\n        displayName: Generate LocProject.json\n        condition: ${{ parameters.condition }}\n\n    - task: OneLocBuild@2\n      displayName: OneLocBuild\n      env:\n        SYSTEM_ACCESSTOKEN: $(System.AccessToken)\n      inputs:\n        locProj: eng/Localize/LocProject.json\n        outDir: $(Build.ArtifactStagingDirectory)\n        lclSource: ${{ parameters.LclSource }}\n        lclPackageId: ${{ parameters.LclPackageId }}\n        isCreatePrSelected: ${{ parameters.CreatePr }}\n        isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }}\n        ${{ if eq(parameters.CreatePr, true) }}:\n          isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }}\n          ${{ if eq(parameters.RepoType, 'gitHub') }}:\n            isShouldReusePrSelected: ${{ parameters.ReusePr }}\n        packageSourceAuth: patAuth\n        patVariable: ${{ parameters.CeapexPat }}\n        ${{ if eq(parameters.RepoType, 'gitHub') }}:\n          repoType: ${{ parameters.RepoType }}\n          gitHubPatVariable: \"${{ parameters.GithubPat }}\"\n        ${{ if ne(parameters.MirrorRepo, '') }}:\n          isMirrorRepoSelected: true\n          gitHubOrganization: ${{ parameters.GitHubOrg }}\n          mirrorRepo: ${{ parameters.MirrorRepo }}\n          mirrorBranch: ${{ parameters.MirrorBranch }}\n      condition: ${{ parameters.condition }}\n\n    - template: /eng/common/core-templates/steps/publish-build-artifacts.yml\n      parameters:\n        is1ESPipeline: ${{ parameters.is1ESPipeline }}\n        args:\n          displayName: Publish Localization Files\n          pathToPublish: '$(Build.ArtifactStagingDirectory)/loc'\n          publishLocation: Container\n          artifactName: Loc\n          condition: ${{ parameters.condition }}\n\n    - template: /eng/common/core-templates/steps/publish-build-artifacts.yml\n      parameters:\n        is1ESPipeline: ${{ parameters.is1ESPipeline }}\n        args:\n          displayName: Publish LocProject.json\n          pathToPublish: '$(Build.SourcesDirectory)/eng/Localize/'\n          publishLocation: Container\n          artifactName: Loc\n          condition: ${{ parameters.condition }}"
  },
  {
    "path": "eng/common/core-templates/job/publish-build-assets.yml",
    "content": "parameters:\n  configuration: 'Debug'\n\n  # Optional: condition for the job to run\n  condition: ''\n\n  # Optional: 'true' if future jobs should run even if this job fails\n  continueOnError: false\n\n  # Optional: dependencies of the job\n  dependsOn: ''\n\n  # Optional: Include PublishBuildArtifacts task\n  enablePublishBuildArtifacts: false\n\n  # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool\n  pool: {}\n\n  # Optional: should run as a public build even in the internal project\n  #           if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.\n  runAsPublic: false\n\n  # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing\n  publishUsingPipelines: false\n\n  # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing\n  publishAssetsImmediately: false\n\n  artifactsPublishingAdditionalParameters: ''\n\n  signingValidationAdditionalParameters: ''\n\n  is1ESPipeline: ''\n\njobs:\n- job: Asset_Registry_Publish\n\n  dependsOn: ${{ parameters.dependsOn }}\n  timeoutInMinutes: 150\n\n  ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:\n    displayName: Publish Assets\n  ${{ else }}:\n    displayName: Publish to Build Asset Registry\n\n  variables:\n  - template: /eng/common/core-templates/variables/pool-providers.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n  - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:\n    - group: Publish-Build-Assets\n    - group: AzureDevOps-Artifact-Feeds-Pats\n    - name: runCodesignValidationInjection\n      value: false\n    # unconditional - needed for logs publishing (redactor tool version)\n    - template: /eng/common/core-templates/post-build/common-variables.yml\n\n  pool:\n    # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)\n    ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:\n      name: AzurePipelines-EO\n      image: 1ESPT-Windows2022\n      demands: Cmd\n      os: windows\n    # If it's not devdiv, it's dnceng\n    ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:\n      name: NetCore1ESPool-Publishing-Internal\n      image: windows.vs2019.amd64\n      os: windows\n  steps:\n  - ${{ if eq(parameters.is1ESPipeline, '') }}:\n    - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error\n\n  - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:\n    - checkout: self\n      fetchDepth: 3\n      clean: true\n      \n    - task: DownloadBuildArtifacts@0\n      displayName: Download artifact\n      inputs:\n        artifactName: AssetManifests\n        downloadPath: '$(Build.StagingDirectory)/Download'\n        checkDownloadedFiles: true\n      condition: ${{ parameters.condition }}\n      continueOnError: ${{ parameters.continueOnError }}\n    \n    - task: NuGetAuthenticate@1\n\n    - task: AzureCLI@2\n      displayName: Publish Build Assets\n      inputs:\n        azureSubscription: \"Darc: Maestro Production\"\n        scriptType: ps\n        scriptLocation: scriptPath\n        scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1\n        arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet\n          /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests'\n          /p:MaestroApiEndpoint=https://maestro.dot.net\n          /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }}\n          /p:OfficialBuildId=$(Build.BuildNumber)\n      condition: ${{ parameters.condition }}\n      continueOnError: ${{ parameters.continueOnError }}\n    \n    - task: powershell@2\n      displayName: Create ReleaseConfigs Artifact\n      inputs:\n        targetType: inline\n        script: |\n          New-Item -Path \"$(Build.StagingDirectory)/ReleaseConfigs\" -ItemType Directory -Force\n          $filePath = \"$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt\"\n          Add-Content -Path $filePath -Value $(BARBuildId)\n          Add-Content -Path $filePath -Value \"$(DefaultChannels)\"\n          Add-Content -Path $filePath -Value $(IsStableBuild)\n\n          $symbolExclusionfile = \"$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt\"\n          if (Test-Path -Path $symbolExclusionfile)\n          {\n            Write-Host \"SymbolExclusionFile exists\"\n            Copy-Item -Path $symbolExclusionfile -Destination \"$(Build.StagingDirectory)/ReleaseConfigs\"\n          }\n\n    - template: /eng/common/core-templates/steps/publish-build-artifacts.yml\n      parameters:\n        is1ESPipeline: ${{ parameters.is1ESPipeline }}\n        args:\n          displayName: Publish ReleaseConfigs Artifact\n          pathToPublish: '$(Build.StagingDirectory)/ReleaseConfigs'\n          publishLocation: Container\n          artifactName: ReleaseConfigs\n\n    - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:\n      - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml\n        parameters:\n          BARBuildId: ${{ parameters.BARBuildId }}\n          PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}\n          is1ESPipeline: ${{ parameters.is1ESPipeline }}\n\n      - task: AzureCLI@2\n        displayName: Publish Using Darc\n        inputs:\n          azureSubscription: \"Darc: Maestro Production\"\n          scriptType: ps\n          scriptLocation: scriptPath\n          scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1\n          arguments: >\n            -BuildId $(BARBuildId)\n            -PublishingInfraVersion 3\n            -AzdoToken '$(System.AccessToken)'\n            -WaitPublishingFinish true\n            -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'\n            -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'\n\n    - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:\n      - template: /eng/common/core-templates/steps/publish-logs.yml\n        parameters:\n          is1ESPipeline: ${{ parameters.is1ESPipeline }}\n          JobLabel: 'Publish_Artifacts_Logs'     \n"
  },
  {
    "path": "eng/common/core-templates/job/source-build.yml",
    "content": "parameters:\n  # This template adds arcade-powered source-build to CI. The template produces a server job with a\n  # default ID 'Source_Build_Complete' to put in a dependency list if necessary.\n\n  # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed.\n  jobNamePrefix: 'Source_Build'\n\n  # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for\n  # managed-only repositories. This is an object with these properties:\n  #\n  # name: ''\n  #   The name of the job. This is included in the job ID.\n  # targetRID: ''\n  #   The name of the target RID to use, instead of the one auto-detected by Arcade.\n  # portableBuild: false\n  #   Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than\n  #   linux-x64), and compiling against distro-provided packages rather than portable ones. The\n  #   default is portable mode.\n  # skipPublishValidation: false\n  #   Disables publishing validation.  By default, a check is performed to ensure no packages are\n  #   published by source-build.\n  # container: ''\n  #   A container to use. Runs in docker.\n  # pool: {}\n  #   A pool to use. Runs directly on an agent.\n  # buildScript: ''\n  #   Specifies the build script to invoke to perform the build in the repo. The default\n  #   './build.sh' should work for typical Arcade repositories, but this is customizable for\n  #   difficult situations.\n  # jobProperties: {}\n  #   A list of job properties to inject at the top level, for potential extensibility beyond\n  #   container and pool.\n  platform: {}\n\n  is1ESPipeline: ''\n\n  # If set to true and running on a non-public project,\n  # Internal nuget and blob storage locations will be enabled.\n  # This is not enabled by default because many repositories do not need internal sources\n  # and do not need to have the required service connections approved in the pipeline.\n  enableInternalSources: false\n\njobs:\n- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }}\n  displayName: Source-Build (${{ parameters.platform.name }})\n\n  ${{ each property in parameters.platform.jobProperties }}:\n    ${{ property.key }}: ${{ property.value }}\n\n  ${{ if ne(parameters.platform.container, '') }}:\n    container: ${{ parameters.platform.container }}\n\n  ${{ if eq(parameters.platform.pool, '') }}:\n    # The default VM host AzDO pool. This should be capable of running Docker containers: almost all\n    # source-build builds run in Docker, including the default managed platform.\n    # /eng/common/core-templates/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic\n    ${{ if eq(parameters.is1ESPipeline, 'true') }}:\n      pool:\n        ${{ if eq(variables['System.TeamProject'], 'public') }}:\n          name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')]\n          demands: ImageOverride -equals build.ubuntu.2004.amd64\n        ${{ if eq(variables['System.TeamProject'], 'internal') }}:\n          name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')]\n          image: 1es-mariner-2\n          os: linux\n    ${{ else }}:\n      pool:\n        ${{ if eq(variables['System.TeamProject'], 'public') }}:\n          name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')]\n          demands: ImageOverride -equals Build.Ubuntu.2204.Amd64.Open\n        ${{ if eq(variables['System.TeamProject'], 'internal') }}:\n          name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')]\n          demands: ImageOverride -equals Build.Ubuntu.2204.Amd64\n  ${{ if ne(parameters.platform.pool, '') }}:\n    pool: ${{ parameters.platform.pool }}\n\n  workspace:\n    clean: all\n\n  steps:\n  - ${{ if eq(parameters.is1ESPipeline, '') }}:\n    - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error\n\n  - ${{ if eq(parameters.enableInternalSources, true) }}:\n    - template: /eng/common/core-templates/steps/enable-internal-sources.yml\n      parameters:\n        is1ESPipeline: ${{ parameters.is1ESPipeline }}\n    - template: /eng/common/core-templates/steps/enable-internal-runtimes.yml\n      parameters:\n        is1ESPipeline: ${{ parameters.is1ESPipeline }}\n  - template: /eng/common/core-templates/steps/source-build.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n      platform: ${{ parameters.platform }}\n"
  },
  {
    "path": "eng/common/core-templates/job/source-index-stage1.yml",
    "content": "parameters:\n  runAsPublic: false\n  sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command \"eng/common/build.ps1 -restore -build -binarylog -ci\"\n  preSteps: []\n  binlogPath: artifacts/log/Debug/Build.binlog\n  condition: ''\n  dependsOn: ''\n  pool: ''\n  is1ESPipeline: ''\n\njobs:\n- job: SourceIndexStage1\n  dependsOn: ${{ parameters.dependsOn }}\n  condition: ${{ parameters.condition }}\n  variables:\n  - name: BinlogPath\n    value: ${{ parameters.binlogPath }}\n  - template: /eng/common/core-templates/variables/pool-providers.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n\n  ${{ if ne(parameters.pool, '') }}:\n    pool: ${{ parameters.pool }}\n  ${{ if eq(parameters.pool, '') }}:\n    pool:\n      ${{ if eq(variables['System.TeamProject'], 'public') }}:\n        name: $(DncEngPublicBuildPool)\n        image: windows.vs2022.amd64.open\n      ${{ if eq(variables['System.TeamProject'], 'internal') }}:\n        name: $(DncEngInternalBuildPool)\n        image: windows.vs2022.amd64\n\n  steps:\n  - ${{ if eq(parameters.is1ESPipeline, '') }}:\n    - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error\n\n  - ${{ each preStep in parameters.preSteps }}:\n    - ${{ preStep }}\n  - script: ${{ parameters.sourceIndexBuildCommand }}\n    displayName: Build Repository\n\n  - template: /eng/common/core-templates/steps/source-index-stage1-publish.yml\n    parameters:\n      binLogPath: ${{ parameters.binLogPath }}"
  },
  {
    "path": "eng/common/core-templates/jobs/codeql-build.yml",
    "content": "parameters:\n  # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md\n  continueOnError: false\n  # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job\n  jobs: []\n  # Optional: if specified, restore and use this version of Guardian instead of the default.\n  overrideGuardianVersion: ''\n  is1ESPipeline: ''\n\njobs:\n- template: /eng/common/core-templates/jobs/jobs.yml\n  parameters:\n    is1ESPipeline: ${{ parameters.is1ESPipeline }}\n    enableMicrobuild: false\n    enablePublishBuildArtifacts: false\n    enablePublishTestResults: false\n    enablePublishBuildAssets: false\n    enablePublishUsingPipelines: false\n    enableTelemetry: true\n\n    variables:\n      - group: Publish-Build-Assets\n      # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in\n      # sync with the packages.config file.\n      - name: DefaultGuardianVersion\n        value: 0.109.0\n      - name: GuardianPackagesConfigFile\n        value: $(Build.SourcesDirectory)\\eng\\common\\sdl\\packages.config\n      - name: GuardianVersion\n        value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}\n  \n    jobs: ${{ parameters.jobs }}\n        \n"
  },
  {
    "path": "eng/common/core-templates/jobs/jobs.yml",
    "content": "parameters:\n  # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md\n  continueOnError: false\n\n  # Optional: Include PublishBuildArtifacts task\n  enablePublishBuildArtifacts: false\n\n  # Optional: Enable publishing using release pipelines\n  enablePublishUsingPipelines: false\n\n  # Optional: Enable running the source-build jobs to build repo from source\n  enableSourceBuild: false\n\n  # Optional: Parameters for source-build template.\n  #           See /eng/common/core-templates/jobs/source-build.yml for options\n  sourceBuildParameters: []\n\n  graphFileGeneration:\n    # Optional: Enable generating the graph files at the end of the build\n    enabled: false\n    # Optional: Include toolset dependencies in the generated graph files\n    includeToolset: false\n    \n  # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job\n  jobs: []\n\n  # Optional: Override automatically derived dependsOn value for \"publish build assets\" job\n  publishBuildAssetsDependsOn: ''\n\n  # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage.\n  publishAssetsImmediately: false\n\n  # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml)\n  artifactsPublishingAdditionalParameters: ''\n  signingValidationAdditionalParameters: ''\n\n  # Optional: should run as a public build even in the internal project\n  #           if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.\n  runAsPublic: false\n\n  enableSourceIndex: false\n  sourceIndexParams: {}\n\n  artifacts: {}\n  is1ESPipeline: ''\n\n# Internal resources (telemetry, microbuild) can only be accessed from non-public projects,\n# and some (Microbuild) should only be applied to non-PR cases for internal builds.\n\njobs:\n- ${{ each job in parameters.jobs }}:\n  - ${{ if eq(parameters.is1ESPipeline, 'true') }}:\n    - template: /eng/common/templates-official/job/job.yml\n      parameters: \n        # pass along parameters\n        ${{ each parameter in parameters }}:\n          ${{ if ne(parameter.key, 'jobs') }}:\n            ${{ parameter.key }}: ${{ parameter.value }}\n\n        # pass along job properties\n        ${{ each property in job }}:\n          ${{ if ne(property.key, 'job') }}:\n            ${{ property.key }}: ${{ property.value }}\n\n        name: ${{ job.job }}\n\n  - ${{ else }}:\n    - template: /eng/common/templates/job/job.yml\n      parameters: \n        # pass along parameters\n        ${{ each parameter in parameters }}:\n          ${{ if ne(parameter.key, 'jobs') }}:\n            ${{ parameter.key }}: ${{ parameter.value }}\n\n        # pass along job properties\n        ${{ each property in job }}:\n          ${{ if ne(property.key, 'job') }}:\n            ${{ property.key }}: ${{ property.value }}\n\n        name: ${{ job.job }}\n\n- ${{ if eq(parameters.enableSourceBuild, true) }}:\n  - template: /eng/common/core-templates/jobs/source-build.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n      allCompletedJobId: Source_Build_Complete\n      ${{ each parameter in parameters.sourceBuildParameters }}:\n        ${{ parameter.key }}: ${{ parameter.value }}\n\n- ${{ if eq(parameters.enableSourceIndex, 'true') }}:\n  - template: ../job/source-index-stage1.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n      runAsPublic: ${{ parameters.runAsPublic }}\n      ${{ each parameter in parameters.sourceIndexParams }}:\n        ${{ parameter.key }}: ${{ parameter.value }}\n\n- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:\n  - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}:\n    - template: ../job/publish-build-assets.yml\n      parameters:\n        is1ESPipeline: ${{ parameters.is1ESPipeline }}\n        continueOnError: ${{ parameters.continueOnError }}\n        dependsOn:\n        - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}:\n          - ${{ each job in parameters.publishBuildAssetsDependsOn }}:\n            - ${{ job.job }}\n        - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}:\n          - ${{ each job in parameters.jobs }}:\n            - ${{ job.job }}\n        - ${{ if eq(parameters.enableSourceBuild, true) }}:\n          - Source_Build_Complete\n\n        runAsPublic: ${{ parameters.runAsPublic }}\n        publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }}\n        publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }}\n        enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}\n        artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}\n        signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }}\n"
  },
  {
    "path": "eng/common/core-templates/jobs/source-build.yml",
    "content": "parameters:\n  # This template adds arcade-powered source-build to CI. A job is created for each platform, as\n  # well as an optional server job that completes when all platform jobs complete.\n\n  # The name of the \"join\" job for all source-build platforms. If set to empty string, the job is\n  # not included. Existing repo pipelines can use this job depend on all source-build jobs\n  # completing without maintaining a separate list of every single job ID: just depend on this one\n  # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'.\n  allCompletedJobId: ''\n\n  # See /eng/common/core-templates/job/source-build.yml\n  jobNamePrefix: 'Source_Build'\n\n  # This is the default platform provided by Arcade, intended for use by a managed-only repo.\n  defaultManagedPlatform:\n    name: 'Managed'\n    container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9'\n\n  # Defines the platforms on which to run build jobs. One job is created for each platform, and the\n  # object in this array is sent to the job template as 'platform'. If no platforms are specified,\n  # one job runs on 'defaultManagedPlatform'.\n  platforms: []\n\n  is1ESPipeline: ''\n\n  # If set to true and running on a non-public project,\n  # Internal nuget and blob storage locations will be enabled.\n  # This is not enabled by default because many repositories do not need internal sources\n  # and do not need to have the required service connections approved in the pipeline.\n  enableInternalSources: false\n\njobs:\n\n- ${{ if ne(parameters.allCompletedJobId, '') }}:\n  - job: ${{ parameters.allCompletedJobId }}\n    displayName: Source-Build Complete\n    pool: server\n    dependsOn:\n    - ${{ each platform in parameters.platforms }}:\n      - ${{ parameters.jobNamePrefix }}_${{ platform.name }}\n    - ${{ if eq(length(parameters.platforms), 0) }}:\n      - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }}\n\n- ${{ each platform in parameters.platforms }}:\n  - template: /eng/common/core-templates/job/source-build.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n      jobNamePrefix: ${{ parameters.jobNamePrefix }}\n      platform: ${{ platform }}\n      enableInternalSources: ${{ parameters.enableInternalSources }}\n\n- ${{ if eq(length(parameters.platforms), 0) }}:\n  - template: /eng/common/core-templates/job/source-build.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n      jobNamePrefix: ${{ parameters.jobNamePrefix }}\n      platform: ${{ parameters.defaultManagedPlatform }}\n      enableInternalSources: ${{ parameters.enableInternalSources }}\n"
  },
  {
    "path": "eng/common/core-templates/post-build/common-variables.yml",
    "content": "variables:\n  - group: Publish-Build-Assets\n\n  # Whether the build is internal or not\n  - name: IsInternalBuild\n    value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }}\n\n  # Default Maestro++ API Endpoint and API Version\n  - name: MaestroApiEndPoint\n    value: \"https://maestro.dot.net\"\n  - name: MaestroApiVersion\n    value: \"2020-02-20\"\n\n  - name: SourceLinkCLIVersion\n    value: 3.0.0\n  - name: SymbolToolVersion\n    value: 1.0.1\n  - name: BinlogToolVersion\n    value: 1.0.11\n\n  - name: runCodesignValidationInjection\n    value: false\n"
  },
  {
    "path": "eng/common/core-templates/post-build/post-build.yml",
    "content": "parameters:\n  # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST.\n  # Publishing V1 is no longer supported\n  # Publishing V2 is no longer supported\n  # Publishing V3 is the default\n  - name: publishingInfraVersion\n    displayName: Which version of publishing should be used to promote the build definition?\n    type: number\n    default: 3\n    values:\n    - 3\n\n  - name: BARBuildId\n    displayName: BAR Build Id\n    type: number\n    default: 0\n\n  - name: PromoteToChannelIds\n    displayName: Channel to promote BARBuildId to\n    type: string\n    default: ''\n\n  - name: enableSourceLinkValidation\n    displayName: Enable SourceLink validation\n    type: boolean\n    default: false\n\n  - name: enableSigningValidation\n    displayName: Enable signing validation\n    type: boolean\n    default: true\n\n  - name: enableSymbolValidation\n    displayName: Enable symbol validation\n    type: boolean\n    default: false\n\n  - name: enableNugetValidation\n    displayName: Enable NuGet validation\n    type: boolean\n    default: true\n    \n  - name: publishInstallersAndChecksums\n    displayName: Publish installers and checksums\n    type: boolean\n    default: true\n    \n  - name: requireDefaultChannels\n    displayName: Fail the build if there are no default channel(s) registrations for the current build\n    type: boolean\n    default: false\n\n  - name: SDLValidationParameters\n    type: object\n    default:\n      enable: false\n      publishGdn: false\n      continueOnError: false\n      params: ''\n      artifactNames: ''\n      downloadArtifacts: true\n\n  # These parameters let the user customize the call to sdk-task.ps1 for publishing\n  # symbols & general artifacts as well as for signing validation\n  - name: symbolPublishingAdditionalParameters\n    displayName: Symbol publishing additional parameters\n    type: string\n    default: ''\n\n  - name: artifactsPublishingAdditionalParameters\n    displayName: Artifact publishing additional parameters\n    type: string\n    default: ''\n\n  - name: signingValidationAdditionalParameters\n    displayName: Signing validation additional parameters\n    type: string\n    default: ''\n\n  # Which stages should finish execution before post-build stages start\n  - name: validateDependsOn\n    type: object\n    default:\n    - build\n\n  - name: publishDependsOn\n    type: object\n    default:\n    - Validate\n\n  # Optional: Call asset publishing rather than running in a separate stage\n  - name: publishAssetsImmediately\n    type: boolean\n    default: false\n\n  - name: is1ESPipeline\n    type: boolean\n    default: false\n\nstages:\n- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:\n  - stage: Validate\n    dependsOn: ${{ parameters.validateDependsOn }}\n    displayName: Validate Build Assets\n    variables:\n      - template: /eng/common/core-templates/post-build/common-variables.yml\n      - template: /eng/common/core-templates/variables/pool-providers.yml\n        parameters:\n          is1ESPipeline: ${{ parameters.is1ESPipeline }}\n    jobs:\n    - job:\n      displayName: NuGet Validation\n      condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true'))\n      pool:\n        # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)\n        ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:\n          name: AzurePipelines-EO\n          image: 1ESPT-Windows2022\n          demands: Cmd\n          os: windows\n        # If it's not devdiv, it's dnceng\n        ${{ else }}:\n          ${{ if eq(parameters.is1ESPipeline, true) }}:\n            name: $(DncEngInternalBuildPool)\n            image: windows.vs2022.amd64\n            os: windows\n          ${{ else }}:\n            name: $(DncEngInternalBuildPool)\n            demands: ImageOverride -equals windows.vs2022.amd64\n\n      steps:\n        - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml\n          parameters:\n            BARBuildId: ${{ parameters.BARBuildId }}\n            PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}\n            is1ESPipeline: ${{ parameters.is1ESPipeline }}\n\n        - task: DownloadBuildArtifacts@0\n          displayName: Download Package Artifacts\n          inputs:\n            buildType: specific\n            buildVersionToDownload: specific\n            project: $(AzDOProjectName)\n            pipeline: $(AzDOPipelineId)\n            buildId: $(AzDOBuildId)\n            artifactName: PackageArtifacts\n            checkDownloadedFiles: true\n\n        - task: PowerShell@2\n          displayName: Validate\n          inputs:\n            filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1\n            arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/\n\n    - job:\n      displayName: Signing Validation\n      condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true'))\n      pool:\n        # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)\n        ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:\n          name: AzurePipelines-EO\n          image: 1ESPT-Windows2022\n          demands: Cmd\n          os: windows\n        # If it's not devdiv, it's dnceng\n        ${{ else }}:\n          ${{ if eq(parameters.is1ESPipeline, true) }}:        \n            name: $(DncEngInternalBuildPool)\n            image: 1es-windows-2022\n            os: windows\n          ${{ else }}:\n            name: $(DncEngInternalBuildPool)\n            demands: ImageOverride -equals windows.vs2022.amd64          \n      steps:\n        - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml\n          parameters:\n            BARBuildId: ${{ parameters.BARBuildId }}\n            PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}\n            is1ESPipeline: ${{ parameters.is1ESPipeline }}\n\n        - task: DownloadBuildArtifacts@0\n          displayName: Download Package Artifacts\n          inputs:\n            buildType: specific\n            buildVersionToDownload: specific\n            project: $(AzDOProjectName)\n            pipeline: $(AzDOPipelineId)\n            buildId: $(AzDOBuildId)\n            artifactName: PackageArtifacts\n            checkDownloadedFiles: true\n            itemPattern: |\n              **\n              !**/Microsoft.SourceBuild.Intermediate.*.nupkg\n\n        # This is necessary whenever we want to publish/restore to an AzDO private feed\n        # Since sdk-task.ps1 tries to restore packages we need to do this authentication here\n        # otherwise it'll complain about accessing a private feed.\n        - task: NuGetAuthenticate@1\n          displayName: 'Authenticate to AzDO Feeds'\n\n        # Signing validation will optionally work with the buildmanifest file which is downloaded from\n        # Azure DevOps above.\n        - task: PowerShell@2\n          displayName: Validate\n          inputs:\n            filePath: eng\\common\\sdk-task.ps1\n            arguments: -task SigningValidation -restore -msbuildEngine vs\n              /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts'\n              /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt'\n              ${{ parameters.signingValidationAdditionalParameters }}\n\n        - template: /eng/common/core-templates/steps/publish-logs.yml\n          parameters:\n            is1ESPipeline: ${{ parameters.is1ESPipeline }}\n            StageLabel: 'Validation'\n            JobLabel: 'Signing'\n            BinlogToolVersion: $(BinlogToolVersion)\n\n    - job:\n      displayName: SourceLink Validation\n      condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true')\n      pool:\n        # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)\n        ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:\n          name: AzurePipelines-EO\n          image: 1ESPT-Windows2022\n          demands: Cmd\n          os: windows\n        # If it's not devdiv, it's dnceng\n        ${{ else }}:\n          ${{ if eq(parameters.is1ESPipeline, true) }}:          \n            name: $(DncEngInternalBuildPool)\n            image: 1es-windows-2022\n            os: windows\n          ${{ else }}:\n            name: $(DncEngInternalBuildPool)\n            demands: ImageOverride -equals windows.vs2022.amd64          \n      steps:\n        - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml\n          parameters:\n            BARBuildId: ${{ parameters.BARBuildId }}\n            PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}\n            is1ESPipeline: ${{ parameters.is1ESPipeline }}\n\n        - task: DownloadBuildArtifacts@0\n          displayName: Download Blob Artifacts\n          inputs:\n            buildType: specific\n            buildVersionToDownload: specific\n            project: $(AzDOProjectName)\n            pipeline: $(AzDOPipelineId)\n            buildId: $(AzDOBuildId)\n            artifactName: BlobArtifacts\n            checkDownloadedFiles: true\n\n        - task: PowerShell@2\n          displayName: Validate\n          inputs:\n            filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1\n            arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ \n              -ExtractPath $(Agent.BuildDirectory)/Extract/ \n              -GHRepoName $(Build.Repository.Name) \n              -GHCommit $(Build.SourceVersion)\n              -SourcelinkCliVersion $(SourceLinkCLIVersion)\n          continueOnError: true\n\n- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}:\n  - stage: publish_using_darc\n    ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:\n      dependsOn: ${{ parameters.publishDependsOn }}\n    ${{ else }}:\n      dependsOn: ${{ parameters.validateDependsOn }}\n    displayName: Publish using Darc\n    variables:\n      - template: /eng/common/core-templates/post-build/common-variables.yml\n      - template: /eng/common/core-templates/variables/pool-providers.yml\n        parameters:\n          is1ESPipeline: ${{ parameters.is1ESPipeline }}\n    jobs:\n    - job:\n      displayName: Publish Using Darc\n      timeoutInMinutes: 120\n      pool:\n        # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)\n        ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:\n          name: AzurePipelines-EO\n          image: 1ESPT-Windows2022\n          demands: Cmd\n          os: windows\n        # If it's not devdiv, it's dnceng\n        ${{ else }}:\n          ${{ if eq(parameters.is1ESPipeline, true) }}:          \n            name: NetCore1ESPool-Publishing-Internal\n            image: windows.vs2019.amd64\n            os: windows\n          ${{ else }}:\n            name: NetCore1ESPool-Publishing-Internal\n            demands: ImageOverride -equals windows.vs2019.amd64          \n      steps:\n        - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml\n          parameters:\n            BARBuildId: ${{ parameters.BARBuildId }}\n            PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}\n            is1ESPipeline: ${{ parameters.is1ESPipeline }}\n\n        - task: NuGetAuthenticate@1\n\n        - task: AzureCLI@2\n          displayName: Publish Using Darc\n          inputs:\n            azureSubscription: \"Darc: Maestro Production\"\n            scriptType: ps\n            scriptLocation: scriptPath\n            scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1\n            arguments: >\n              -BuildId $(BARBuildId)\n              -PublishingInfraVersion ${{ parameters.publishingInfraVersion }}\n              -AzdoToken '$(System.AccessToken)'\n              -WaitPublishingFinish true\n              -RequireDefaultChannels ${{ parameters.requireDefaultChannels }}\n              -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'\n              -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'\n"
  },
  {
    "path": "eng/common/core-templates/post-build/setup-maestro-vars.yml",
    "content": "parameters:\n  BARBuildId: ''\n  PromoteToChannelIds: ''\n  is1ESPipeline: ''\n\nsteps:\n  - ${{ if eq(parameters.is1ESPipeline, '') }}:\n    - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error\n\n  - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:\n    - task: DownloadBuildArtifacts@0\n      displayName: Download Release Configs\n      inputs:\n        buildType: current\n        artifactName: ReleaseConfigs\n        checkDownloadedFiles: true\n\n  - task: AzureCLI@2\n    name: setReleaseVars\n    displayName: Set Release Configs Vars\n    inputs:\n      azureSubscription: \"Darc: Maestro Production\"\n      scriptType: pscore\n      scriptLocation: inlineScript\n      inlineScript: |\n        try {\n          if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') {\n            $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt\n\n            $BarId = $Content | Select -Index 0\n            $Channels = $Content | Select -Index 1\n            $IsStableBuild = $Content | Select -Index 2\n\n            $AzureDevOpsProject = $Env:System_TeamProject\n            $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId\n            $AzureDevOpsBuildId = $Env:Build_BuildId\n          }\n          else {\n            . $(Build.SourcesDirectory)\\eng\\common\\tools.ps1\n            $darc = Get-Darc\n            $buildInfo = & $darc get-build `\n              --id ${{ parameters.BARBuildId }} `\n              --extended `\n              --output-format json `\n              --ci `\n              | convertFrom-Json\n\n            $BarId = ${{ parameters.BARBuildId }}\n            $Channels = $Env:PromoteToMaestroChannels -split \",\"\n            $Channels = $Channels -join \"][\"\n            $Channels = \"[$Channels]\"\n\n            $IsStableBuild = $buildInfo.stable\n            $AzureDevOpsProject = $buildInfo.azureDevOpsProject\n            $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId\n            $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId\n          }\n\n          Write-Host \"##vso[task.setvariable variable=BARBuildId]$BarId\"\n          Write-Host \"##vso[task.setvariable variable=TargetChannels]$Channels\"\n          Write-Host \"##vso[task.setvariable variable=IsStableBuild]$IsStableBuild\"\n\n          Write-Host \"##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject\"\n          Write-Host \"##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId\"\n          Write-Host \"##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId\"\n        }\n        catch {\n          Write-Host $_\n          Write-Host $_.Exception\n          Write-Host $_.ScriptStackTrace\n          exit 1\n        }\n    env:\n      PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }}\n"
  },
  {
    "path": "eng/common/core-templates/steps/cleanup-microbuild.yml",
    "content": "parameters:\n  # Enable cleanup tasks for MicroBuild\n  enableMicrobuild: false\n  # Enable cleanup tasks for MicroBuild on Mac and Linux\n  # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT'\n  enableMicrobuildForMacAndLinux: false\n  continueOnError: false\n\nsteps:\n  - ${{ if eq(parameters.enableMicrobuild, 'true') }}:\n    - task: MicroBuildCleanup@1\n      displayName: Execute Microbuild cleanup tasks\n      condition: and(\n        always(),\n        or(\n          and(\n            eq(variables['Agent.Os'], 'Windows_NT'),\n            in(variables['_SignType'], 'real', 'test')\n          ),\n          and(\n            ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }},\n            ne(variables['Agent.Os'], 'Windows_NT'),\n            eq(variables['_SignType'], 'real')\n          )\n        ))\n      continueOnError: ${{ parameters.continueOnError }}\n      env:\n        TeamName: $(_TeamName)\n"
  },
  {
    "path": "eng/common/core-templates/steps/component-governance.yml",
    "content": "parameters:\n  disableComponentGovernance: false\n  componentGovernanceIgnoreDirectories: ''\n  is1ESPipeline: false\n  displayName: 'Component Detection'\n\nsteps:\n- ${{ if eq(parameters.disableComponentGovernance, 'true') }}:\n  - script: echo \"##vso[task.setvariable variable=skipComponentGovernanceDetection]true\"\n    displayName: Set skipComponentGovernanceDetection variable\n- ${{ if ne(parameters.disableComponentGovernance, 'true') }}:\n  - task: ComponentGovernanceComponentDetection@0\n    continueOnError: true\n    displayName: ${{ parameters.displayName }}\n    inputs:\n      ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}\n"
  },
  {
    "path": "eng/common/core-templates/steps/enable-internal-runtimes.yml",
    "content": "# Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'\n# variable with the base64-encoded SAS token, by default\n\nparameters:\n- name: federatedServiceConnection\n  type: string\n  default: 'dotnetbuilds-internal-read'\n- name: outputVariableName\n  type: string\n  default: 'dotnetbuilds-internal-container-read-token-base64'\n- name: expiryInHours\n  type: number\n  default: 1\n- name: base64Encode\n  type: boolean\n  default: true\n- name: is1ESPipeline\n  type: boolean\n  default: false\n\nsteps:\n- ${{ if ne(variables['System.TeamProject'], 'public') }}:\n  - template: /eng/common/core-templates/steps/get-delegation-sas.yml\n    parameters:\n      federatedServiceConnection: ${{ parameters.federatedServiceConnection }}\n      outputVariableName: ${{ parameters.outputVariableName }}\n      expiryInHours: ${{ parameters.expiryInHours }}\n      base64Encode: ${{ parameters.base64Encode }}\n      storageAccount: dotnetbuilds\n      container: internal\n      permissions: rl\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}"
  },
  {
    "path": "eng/common/core-templates/steps/enable-internal-sources.yml",
    "content": "parameters:\n# This is the Azure federated service connection that we log into to get an access token.\n- name: nugetFederatedServiceConnection\n  type: string\n  default: 'dnceng-artifacts-feeds-read'\n- name: is1ESPipeline\n  type: boolean\n  default: false\n# Legacy parameters to allow for PAT usage\n- name: legacyCredential\n  type: string\n  default: ''\n\nsteps:\n- ${{ if ne(variables['System.TeamProject'], 'public') }}:\n  - ${{ if ne(parameters.legacyCredential, '') }}:\n    - task: PowerShell@2\n      displayName: Setup Internal Feeds\n      inputs:\n        filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1\n        arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token\n      env:\n        Token: ${{ parameters.legacyCredential }}\n  # If running on dnceng (internal project), just use the default behavior for NuGetAuthenticate.\n  # If running on DevDiv, NuGetAuthenticate is not really an option. It's scoped to a single feed, and we have many feeds that\n  # may be added. Instead, we'll use the traditional approach (add cred to nuget.config), but use an account token.\n  - ${{ else }}:\n    - ${{ if eq(variables['System.TeamProject'], 'internal') }}:\n      - task: PowerShell@2\n        displayName: Setup Internal Feeds\n        inputs:\n          filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1\n          arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config\n    - ${{ else }}:\n      - template: /eng/common/templates/steps/get-federated-access-token.yml\n        parameters:\n          federatedServiceConnection: ${{ parameters.nugetFederatedServiceConnection }}\n          outputVariableName: 'dnceng-artifacts-feeds-read-access-token'\n      - task: PowerShell@2\n        displayName: Setup Internal Feeds\n        inputs:\n          filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1\n          arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $(dnceng-artifacts-feeds-read-access-token)\n  # This is required in certain scenarios to install the ADO credential provider.\n  # It installed by default in some msbuild invocations (e.g. VS msbuild), but needs to be installed for others\n  # (e.g. dotnet msbuild).\n  - task: NuGetAuthenticate@1\n"
  },
  {
    "path": "eng/common/core-templates/steps/generate-sbom.yml",
    "content": "# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated.\n# PackageName - The name of the package this SBOM represents.\n# PackageVersion - The version of the package this SBOM represents. \n# ManifestDirPath - The path of the directory where the generated manifest files will be placed\n# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.\n\nparameters:\n  PackageVersion: 9.0.0\n  BuildDropPath: '$(Build.SourcesDirectory)/artifacts'\n  PackageName: '.NET'\n  ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom\n  IgnoreDirectories: ''\n  sbomContinueOnError: true\n  is1ESPipeline: false\n  # disable publishArtifacts if some other step is publishing the artifacts (like job.yml).\n  publishArtifacts: true\n\nsteps:\n- task: PowerShell@2 \n  displayName: Prep for SBOM generation in (Non-linux)\n  condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin'))\n  inputs: \n    filePath: ./eng/common/generate-sbom-prep.ps1\n    arguments: ${{parameters.manifestDirPath}}\n\n# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461\n- script: |\n    chmod +x ./eng/common/generate-sbom-prep.sh\n    ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}}\n  displayName: Prep for SBOM generation in (Linux)\n  condition: eq(variables['Agent.Os'], 'Linux')\n  continueOnError: ${{ parameters.sbomContinueOnError }}\n\n- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0\n  displayName: 'Generate SBOM manifest'\n  continueOnError: ${{ parameters.sbomContinueOnError }}\n  inputs:\n      PackageName: ${{ parameters.packageName }}\n      BuildDropPath: ${{ parameters.buildDropPath }}\n      PackageVersion: ${{ parameters.packageVersion }}\n      ManifestDirPath: ${{ parameters.manifestDirPath }}\n      ${{ if ne(parameters.IgnoreDirectories, '') }}:\n        AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'\n\n- ${{ if eq(parameters.publishArtifacts, 'true')}}:\n  - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n      args:\n        displayName: Publish SBOM manifest\n        continueOnError: ${{parameters.sbomContinueOnError}}\n        targetPath: '${{ parameters.manifestDirPath }}'\n        artifactName: $(ARTIFACT_NAME)\n\n"
  },
  {
    "path": "eng/common/core-templates/steps/get-delegation-sas.yml",
    "content": "parameters:\n- name: federatedServiceConnection\n  type: string\n- name: outputVariableName\n  type: string\n- name: expiryInHours\n  type: number\n  default: 1\n- name: base64Encode\n  type: boolean\n  default: false\n- name: storageAccount\n  type: string\n- name: container\n  type: string\n- name: permissions\n  type: string\n  default: 'rl'\n- name: is1ESPipeline\n  type: boolean\n  default: false\n\nsteps:\n- task: AzureCLI@2\n  displayName: 'Generate delegation SAS Token for ${{ parameters.storageAccount }}/${{ parameters.container }}'\n  inputs:\n    azureSubscription: ${{ parameters.federatedServiceConnection }}\n    scriptType: 'pscore'\n    scriptLocation: 'inlineScript'\n    inlineScript: |\n      # Calculate the expiration of the SAS token and convert to UTC\n      $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString(\"yyyy-MM-ddTHH:mm:ssZ\")\n\n      $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv\n\n      if ($LASTEXITCODE -ne 0) {\n        Write-Error \"Failed to generate SAS token.\"\n        exit 1\n      }\n\n      if ('${{ parameters.base64Encode }}' -eq 'true') {\n        $sas = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($sas))\n      }\n\n      Write-Host \"Setting '${{ parameters.outputVariableName }}' with the access token value\"\n      Write-Host \"##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true]$sas\"\n"
  },
  {
    "path": "eng/common/core-templates/steps/get-federated-access-token.yml",
    "content": "parameters:\n- name: federatedServiceConnection\n  type: string\n- name: outputVariableName\n  type: string\n- name: is1ESPipeline\n  type: boolean\n- name: stepName\n  type: string\n  default: 'getFederatedAccessToken'\n- name: condition\n  type: string\n  default: ''\n# Resource to get a token for. Common values include:\n# - '499b84ac-1321-427f-aa17-267ca6975798' for Azure DevOps\n# - 'https://storage.azure.com/' for storage\n# Defaults to Azure DevOps\n- name: resource\n  type: string\n  default: '499b84ac-1321-427f-aa17-267ca6975798'\n- name: isStepOutputVariable\n  type: boolean\n  default: false\n\nsteps:\n- task: AzureCLI@2\n  displayName: 'Getting federated access token for feeds'\n  name: ${{ parameters.stepName }}\n  ${{ if ne(parameters.condition, '') }}:\n    condition: ${{ parameters.condition }}\n  inputs:\n    azureSubscription: ${{ parameters.federatedServiceConnection }}\n    scriptType: 'pscore'\n    scriptLocation: 'inlineScript'\n    inlineScript: |\n      $accessToken = az account get-access-token --query accessToken --resource ${{ parameters.resource }} --output tsv\n      if ($LASTEXITCODE -ne 0) {\n        Write-Error \"Failed to get access token for resource '${{ parameters.resource }}'\"\n        exit 1\n      }\n      Write-Host \"Setting '${{ parameters.outputVariableName }}' with the access token value\"\n      Write-Host \"##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true;isOutput=${{ parameters.isStepOutputVariable }}]$accessToken\""
  },
  {
    "path": "eng/common/core-templates/steps/install-microbuild.yml",
    "content": "parameters:\n  # Enable install tasks for MicroBuild\n  enableMicrobuild: false\n  # Enable install tasks for MicroBuild on Mac and Linux\n  # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT'\n  enableMicrobuildForMacAndLinux: false\n  # Location of the MicroBuild output folder\n  microBuildOutputFolder: '$(Agent.TempDirectory)'\n  continueOnError: false\n\nsteps:\n  - ${{ if eq(parameters.enableMicrobuild, 'true') }}:\n    - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, 'true') }}:\n      # Install Python 3.12.x on when Python > 3.12.x is installed - https://github.com/dotnet/source-build/issues/4802\n      - script: |\n          version=$(python3 --version | awk '{print $2}')\n          major=$(echo $version | cut -d. -f1)\n          minor=$(echo $version | cut -d. -f2)\n\n          installPython=false\n          if [ \"$major\" -gt 3 ] || { [ \"$major\" -eq 3 ] && [ \"$minor\" -gt 12 ]; }; then\n            installPython=true\n          fi\n\n          echo \"Python version: $version.\"\n          echo \"Install Python 3.12.x: $installPython.\"\n          echo \"##vso[task.setvariable variable=installPython;isOutput=true]$installPython\"\n        name: InstallPython\n        displayName: 'Determine Python installation'\n        condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))\n\n      - task: UsePythonVersion@0\n        inputs:\n          versionSpec: '3.12.x'\n        displayName: 'Use Python 3.12.x'\n        condition: and(succeeded(), eq(variables['InstallPython.installPython'], 'true'), ne(variables['Agent.Os'], 'Windows_NT'))\n\n      # Needed to download the MicroBuild plugin nupkgs on Mac and Linux when nuget.exe is unavailable\n      - task: UseDotNet@2\n        displayName: Install .NET 8.0 SDK for MicroBuild Plugin\n        inputs:\n          packageType: sdk\n          version: 8.0.x\n          installationPath: ${{ parameters.microBuildOutputFolder }}/dotnet\n          workingDirectory: ${{ parameters.microBuildOutputFolder }}\n        condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))\n\n    - task: MicroBuildSigningPlugin@4\n      displayName: Install MicroBuild plugin\n      inputs:\n        signType: $(_SignType)\n        zipSources: false\n        feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json\n        ${{ if and(eq(parameters.enableMicrobuildForMacAndLinux, 'true'), ne(variables['Agent.Os'], 'Windows_NT')) }}:\n          azureSubscription: 'MicroBuild Signing Task (DevDiv)'\n      env:\n        TeamName: $(_TeamName)\n        MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }}\n        SYSTEM_ACCESSTOKEN: $(System.AccessToken)\n      continueOnError: ${{ parameters.continueOnError }}\n      condition: and(\n        succeeded(),\n        or(\n          and(\n            eq(variables['Agent.Os'], 'Windows_NT'),\n            in(variables['_SignType'], 'real', 'test')\n          ),\n          and(\n            ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }},\n            ne(variables['Agent.Os'], 'Windows_NT'),\n            eq(variables['_SignType'], 'real')\n          )\n        ))\n"
  },
  {
    "path": "eng/common/core-templates/steps/publish-build-artifacts.yml",
    "content": "parameters:\n- name: is1ESPipeline\n  type: boolean\n  default: false\n- name: args\n  type: object\n  default: {}\nsteps:\n- ${{ if ne(parameters.is1ESPipeline, true) }}:\n  - template: /eng/common/templates/steps/publish-build-artifacts.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n      ${{ each parameter in parameters.args }}:\n        ${{ parameter.key }}: ${{ parameter.value }}\n- ${{ else }}:\n  - template: /eng/common/templates-official/steps/publish-build-artifacts.yml\n    parameters:\n      is1ESPipeline: ${{ parameters.is1ESPipeline }}\n      ${{ each parameter in parameters.args }}:\n        ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/core-templates/steps/publish-logs.yml",
    "content": "parameters:\n  StageLabel: ''\n  JobLabel: ''\n  CustomSensitiveDataList: ''\n  # A default - in case value from eng/common/core-templates/post-build/common-variables.yml is not passed\n  BinlogToolVersion: '1.0.11'\n  is1ESPipeline: false\n\nsteps:\n- task: Powershell@2\n  displayName: Prepare Binlogs to Upload\n  inputs:\n    targetType: inline\n    script: |\n      New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/\n      Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/\n  continueOnError: true\n  condition: always()\n    \n- task: PowerShell@2\n  displayName: Redact Logs\n  inputs:\n    filePath: $(Build.SourcesDirectory)/eng/common/post-build/redact-logs.ps1\n    # For now this needs to have explicit list of all sensitive data. Taken from eng/publishing/v3/publish.yml\n    # Sensitive data can as well be added to $(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt'\n    #  If the file exists - sensitive data for redaction will be sourced from it\n    #  (single entry per line, lines starting with '# ' are considered comments and skipped)\n    arguments: -InputPath '$(Build.SourcesDirectory)/PostBuildLogs' \n      -BinlogToolVersion ${{parameters.BinlogToolVersion}}\n      -TokensFilePath '$(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt'\n      '$(publishing-dnceng-devdiv-code-r-build-re)'\n      '$(MaestroAccessToken)'\n      '$(dn-bot-all-orgs-artifact-feeds-rw)'\n      '$(akams-client-id)'\n      '$(microsoft-symbol-server-pat)'\n      '$(symweb-symbol-server-pat)'\n      '$(dnceng-symbol-server-pat)'\n      '$(dn-bot-all-orgs-build-rw-code-rw)'\n      '$(System.AccessToken)'\n      ${{parameters.CustomSensitiveDataList}}\n  continueOnError: true\n  condition: always()\n\n- task: CopyFiles@2\n  displayName: Gather post build logs\n  inputs:\n    SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs'\n    Contents: '**'\n    TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'\n  condition: always()\n\n- template: /eng/common/core-templates/steps/publish-build-artifacts.yml\n  parameters:\n    is1ESPipeline: ${{ parameters.is1ESPipeline }}\n    args:\n      displayName: Publish Logs\n      pathToPublish: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'\n      publishLocation: Container\n      artifactName: PostBuildLogs\n      continueOnError: true\n      condition: always()\n"
  },
  {
    "path": "eng/common/core-templates/steps/publish-pipeline-artifacts.yml",
    "content": "parameters:\n- name: is1ESPipeline\n  type: boolean\n  default: false\n\n- name: args\n  type: object\n  default: {}  \n\nsteps:\n- ${{ if ne(parameters.is1ESPipeline, true) }}:\n  - template: /eng/common/templates/steps/publish-pipeline-artifacts.yml\n    parameters:\n      ${{ each parameter in parameters }}:\n        ${{ parameter.key }}: ${{ parameter.value }}\n- ${{ else }}:\n  - template: /eng/common/templates-official/steps/publish-pipeline-artifacts.yml\n    parameters:\n      ${{ each parameter in parameters }}:\n        ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/core-templates/steps/retain-build.yml",
    "content": "parameters:\n  # Optional azure devops PAT with build execute permissions for the build's organization,\n  # only needed if the build that should be retained ran on a different organization than \n  # the pipeline where this template is executing from\n  Token: ''\n  # Optional BuildId to retain, defaults to the current running build\n  BuildId: ''\n  # Azure devops Organization URI for the build in the https://dev.azure.com/<organization> format.\n  # Defaults to the organization the current pipeline is running on\n  AzdoOrgUri: '$(System.CollectionUri)'\n  # Azure devops project for the build. Defaults to the project the current pipeline is running on\n  AzdoProject: '$(System.TeamProject)'\n\nsteps:\n  - task: powershell@2\n    inputs:\n      targetType: 'filePath'\n      filePath: eng/common/retain-build.ps1\n      pwsh: true\n      arguments: >\n        -AzdoOrgUri: ${{parameters.AzdoOrgUri}}\n        -AzdoProject ${{parameters.AzdoProject}}\n        -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }}\n        -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}}\n    displayName: Enable permanent build retention\n    env:\n      SYSTEM_ACCESSTOKEN: $(System.AccessToken)\n      BUILD_ID: $(Build.BuildId)"
  },
  {
    "path": "eng/common/core-templates/steps/send-to-helix.yml",
    "content": "# Please remember to update the documentation if you make changes to these parameters!\nparameters:\n  HelixSource: 'pr/default'              # required -- sources must start with pr/, official/, prodcon/, or agent/\n  HelixType: 'tests/default/'            # required -- Helix telemetry which identifies what type of data this is; should include \"test\" for clarity and must end in '/'\n  HelixBuild: $(Build.BuildNumber)       # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number\n  HelixTargetQueues: ''                  # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues\n  HelixAccessToken: ''                   # required -- access token to make Helix API requests; should be provided by the appropriate variable group\n  HelixProjectPath: 'eng/common/helixpublish.proj'  # optional -- path to the project file to build relative to BUILD_SOURCESDIRECTORY\n  HelixProjectArguments: ''              # optional -- arguments passed to the build command\n  HelixConfiguration: ''                 # optional -- additional property attached to a job\n  HelixPreCommands: ''                   # optional -- commands to run before Helix work item execution\n  HelixPostCommands: ''                  # optional -- commands to run after Helix work item execution\n  WorkItemDirectory: ''                  # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects\n  WorkItemCommand: ''                    # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects\n  WorkItemTimeout: ''                    # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects\n  CorrelationPayloadDirectory: ''        # optional -- a directory to zip up and send to Helix as a correlation payload\n  XUnitProjects: ''                      # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true\n  XUnitWorkItemTimeout: ''               # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects\n  XUnitPublishTargetFramework: ''        # optional -- framework to use to publish your xUnit projects\n  XUnitRuntimeTargetFramework: ''        # optional -- framework to use for the xUnit console runner\n  XUnitRunnerVersion: ''                 # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects\n  IncludeDotNetCli: false                # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion\n  DotNetCliPackageType: ''               # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json\n  DotNetCliVersion: ''                   # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json\n  WaitForWorkItemCompletion: true        # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is \"fire and forget.\"\n  IsExternal: false                      # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set\n  HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net )\n  Creator: ''                            # optional -- if the build is external, use this to specify who is sending the job\n  DisplayNamePrefix: 'Run Tests'         # optional -- rename the beginning of the displayName of the steps in AzDO \n  condition: succeeded()                 # optional -- condition for step to execute; defaults to succeeded()\n  continueOnError: false                 # optional -- determines whether to continue the build if the step errors; defaults to false\n\nsteps:\n  - powershell: 'powershell \"$env:BUILD_SOURCESDIRECTORY\\eng\\common\\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\\artifacts\\log\\$env:BuildConfig\\SendToHelix.binlog\"'\n    displayName: ${{ parameters.DisplayNamePrefix }} (Windows)\n    env:\n      BuildConfig: $(_BuildConfig)\n      HelixSource: ${{ parameters.HelixSource }}\n      HelixType: ${{ parameters.HelixType }}\n      HelixBuild: ${{ parameters.HelixBuild }}\n      HelixConfiguration:  ${{ parameters.HelixConfiguration }}\n      HelixTargetQueues: ${{ parameters.HelixTargetQueues }}\n      HelixAccessToken: ${{ parameters.HelixAccessToken }}\n      HelixPreCommands: ${{ parameters.HelixPreCommands }}\n      HelixPostCommands: ${{ parameters.HelixPostCommands }}\n      WorkItemDirectory: ${{ parameters.WorkItemDirectory }}\n      WorkItemCommand: ${{ parameters.WorkItemCommand }}\n      WorkItemTimeout: ${{ parameters.WorkItemTimeout }}\n      CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}\n      XUnitProjects: ${{ parameters.XUnitProjects }}\n      XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}\n      XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}\n      XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}\n      XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}\n      IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}\n      DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}\n      DotNetCliVersion: ${{ parameters.DotNetCliVersion }}\n      WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}\n      HelixBaseUri: ${{ parameters.HelixBaseUri }}\n      Creator: ${{ parameters.Creator }}\n      SYSTEM_ACCESSTOKEN: $(System.AccessToken)\n    condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT'))\n    continueOnError: ${{ parameters.continueOnError }}\n  - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog\n    displayName: ${{ parameters.DisplayNamePrefix }} (Unix)\n    env:\n      BuildConfig: $(_BuildConfig)\n      HelixSource: ${{ parameters.HelixSource }}\n      HelixType: ${{ parameters.HelixType }}\n      HelixBuild: ${{ parameters.HelixBuild }}\n      HelixConfiguration:  ${{ parameters.HelixConfiguration }}\n      HelixTargetQueues: ${{ parameters.HelixTargetQueues }}\n      HelixAccessToken: ${{ parameters.HelixAccessToken }}\n      HelixPreCommands: ${{ parameters.HelixPreCommands }}\n      HelixPostCommands: ${{ parameters.HelixPostCommands }}\n      WorkItemDirectory: ${{ parameters.WorkItemDirectory }}\n      WorkItemCommand: ${{ parameters.WorkItemCommand }}\n      WorkItemTimeout: ${{ parameters.WorkItemTimeout }}\n      CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}\n      XUnitProjects: ${{ parameters.XUnitProjects }}\n      XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}\n      XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}\n      XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}\n      XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}\n      IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}\n      DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}\n      DotNetCliVersion: ${{ parameters.DotNetCliVersion }}\n      WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}\n      HelixBaseUri: ${{ parameters.HelixBaseUri }}\n      Creator: ${{ parameters.Creator }}\n      SYSTEM_ACCESSTOKEN: $(System.AccessToken)\n    condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT'))\n    continueOnError: ${{ parameters.continueOnError }}\n"
  },
  {
    "path": "eng/common/core-templates/steps/source-build.yml",
    "content": "parameters:\n  # This template adds arcade-powered source-build to CI.\n\n  # This is a 'steps' template, and is intended for advanced scenarios where the existing build\n  # infra has a careful build methodology that must be followed. For example, a repo\n  # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline\n  # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to\n  # GitHub. Using this steps template leaves room for that infra to be included.\n\n  # Defines the platform on which to run the steps. See 'eng/common/core-templates/job/source-build.yml'\n  # for details. The entire object is described in the 'job' template for simplicity, even though\n  # the usage of the properties on this object is split between the 'job' and 'steps' templates.\n  platform: {}\n  is1ESPipeline: false\n\nsteps:\n# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.)\n- script: |\n    set -x\n    df -h\n\n    # If file changes are detected, set CopyWipIntoInnerSourceBuildRepo to copy the WIP changes into the inner source build repo.\n    internalRestoreArgs=\n    if ! git diff --quiet; then\n      internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true'\n      # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo.\n      # This only works if there is a username/email configured, which won't be the case in most CI runs.\n      git config --get user.email\n      if [ $? -ne 0 ]; then\n        git config user.email dn-bot@microsoft.com\n        git config user.name dn-bot\n      fi\n    fi\n\n    # If building on the internal project, the internal storage variable may be available (usually only if needed)\n    # In that case, add variables to allow the download of internal runtimes if the specified versions are not found\n    # in the default public locations.\n    internalRuntimeDownloadArgs=\n    if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then\n      internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)'\n    fi\n\n    buildConfig=Release\n    # Check if AzDO substitutes in a build config from a variable, and use it if so.\n    if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then\n      buildConfig='$(_BuildConfig)'\n    fi\n\n    officialBuildArgs=\n    if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then\n      officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)'\n    fi\n\n    targetRidArgs=\n    if [ '${{ parameters.platform.targetRID }}' != '' ]; then\n      targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}'\n    fi\n\n    runtimeOsArgs=\n    if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then\n      runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}'\n    fi\n\n    baseOsArgs=\n    if [ '${{ parameters.platform.baseOS }}' != '' ]; then\n      baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}'\n    fi\n\n    publishArgs=\n    if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then\n      publishArgs='--publish'\n    fi\n\n    assetManifestFileName=SourceBuild_RidSpecific.xml\n    if [ '${{ parameters.platform.name }}' != '' ]; then\n      assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml\n    fi\n\n    portableBuildArgs=\n    if [ '${{ parameters.platform.portableBuild }}' != '' ]; then\n      portableBuildArgs='/p:PortableBuild=${{ parameters.platform.portableBuild }}'\n    fi\n\n    ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \\\n      --configuration $buildConfig \\\n      --restore --build --pack $publishArgs -bl \\\n      $officialBuildArgs \\\n      $internalRuntimeDownloadArgs \\\n      $internalRestoreArgs \\\n      $targetRidArgs \\\n      $runtimeOsArgs \\\n      $baseOsArgs \\\n      $portableBuildArgs \\\n      /p:DotNetBuildSourceOnly=true \\\n      /p:DotNetBuildRepo=true \\\n      /p:AssetManifestFileName=$assetManifestFileName\n  displayName: Build\n\n# Upload build logs for diagnosis.\n- task: CopyFiles@2\n  displayName: Prepare BuildLogs staging directory\n  inputs:\n    SourceFolder: '$(Build.SourcesDirectory)'\n    Contents: |\n      **/*.log\n      **/*.binlog\n      artifacts/sb/prebuilt-report/**\n    TargetFolder: '$(Build.StagingDirectory)/BuildLogs'\n    CleanTargetFolder: true\n  continueOnError: true\n  condition: succeededOrFailed()\n\n- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml\n  parameters:\n    is1ESPipeline: ${{ parameters.is1ESPipeline }}\n    args:\n      displayName: Publish BuildLogs\n      targetPath: '$(Build.StagingDirectory)/BuildLogs'\n      artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)\n      continueOnError: true\n      condition: succeededOrFailed()\n      sbomEnabled: false  # we don't need SBOM for logs\n\n# Manually inject component detection so that we can ignore the source build upstream cache, which contains\n# a nupkg cache of input packages (a local feed).\n# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir'\n# in src\\Microsoft.DotNet.Arcade.Sdk\\tools\\SourceBuild\\SourceBuildArcade.targets\n- template: /eng/common/core-templates/steps/component-governance.yml\n  parameters:\n    displayName: Component Detection (Exclude upstream cache)\n    is1ESPipeline: ${{ parameters.is1ESPipeline }}\n    componentGovernanceIgnoreDirectories: '$(Build.SourcesDirectory)/artifacts/sb/src/artifacts/obj/source-built-upstream-cache'\n    disableComponentGovernance: ${{ eq(variables['System.TeamProject'], 'public') }}\n"
  },
  {
    "path": "eng/common/core-templates/steps/source-index-stage1-publish.yml",
    "content": "parameters:\n  sourceIndexUploadPackageVersion: 2.0.0-20240522.1\n  sourceIndexProcessBinlogPackageVersion: 1.0.1-20240522.1\n  sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json\n  binlogPath: artifacts/log/Debug/Build.binlog\n\nsteps:\n- task: UseDotNet@2\n  displayName: \"Source Index: Use .NET 8 SDK\"\n  inputs:\n    packageType: sdk\n    version: 8.0.x\n    installationPath: $(Agent.TempDirectory)/dotnet\n    workingDirectory: $(Agent.TempDirectory)\n\n- script: |\n    $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools\n    $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools\n  displayName: \"Source Index: Download netsourceindex Tools\"\n  # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.\n  workingDirectory: $(Agent.TempDirectory)\n\n- script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output\n  displayName: \"Source Index: Process Binlog into indexable sln\"\n\n- ${{ if and(ne(parameters.runAsPublic, 'true'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:\n  - task: AzureCLI@2\n    displayName: \"Source Index: Upload Source Index stage1 artifacts to Azure\"\n    inputs:\n      azureSubscription: 'SourceDotNet Stage1 Publish'\n      addSpnToEnvironment: true\n      scriptType: 'ps'\n      scriptLocation: 'inlineScript'\n      inlineScript: |\n        $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1\n"
  },
  {
    "path": "eng/common/core-templates/variables/pool-providers.yml",
    "content": "parameters:\n  is1ESPipeline: false\n\nvariables:\n  - ${{ if eq(parameters.is1ESPipeline, 'true') }}:\n    - template: /eng/common/templates-official/variables/pool-providers.yml\n  - ${{ else }}:\n    - template: /eng/common/templates/variables/pool-providers.yml"
  },
  {
    "path": "eng/common/cross/arm/tizen/tizen.patch",
    "content": "diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so\n--- a/usr/lib/libc.so\t2016-12-30 23:00:08.284951863 +0900\n+++ b/usr/lib/libc.so\t2016-12-30 23:00:32.140951815 +0900\n@@ -2,4 +2,4 @@\n    Use the shared library, but some functions are only in\n    the static library, so try that secondarily.  */\n OUTPUT_FORMAT(elf32-littlearm)\n-GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-armhf.so.3 ) )\n+GROUP ( libc.so.6 libc_nonshared.a  AS_NEEDED ( ld-linux-armhf.so.3 ) )\n"
  },
  {
    "path": "eng/common/cross/arm64/tizen/tizen.patch",
    "content": "diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so\n--- a/usr/lib64/libc.so\t2016-12-30 23:00:08.284951863 +0900\n+++ b/usr/lib64/libc.so\t2016-12-30 23:00:32.140951815 +0900\n@@ -2,4 +2,4 @@\n    Use the shared library, but some functions are only in\n    the static library, so try that secondarily.  */\n OUTPUT_FORMAT(elf64-littleaarch64)\n-GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) )\n+GROUP ( libc.so.6 libc_nonshared.a  AS_NEEDED ( ld-linux-aarch64.so.1 ) )\n"
  },
  {
    "path": "eng/common/cross/armel/armel.jessie.patch",
    "content": "diff -u -r a/usr/include/urcu/uatomic/generic.h b/usr/include/urcu/uatomic/generic.h\n--- a/usr/include/urcu/uatomic/generic.h\t2014-10-22 15:00:58.000000000 -0700\n+++ b/usr/include/urcu/uatomic/generic.h\t2020-10-30 21:38:28.550000000 -0700\n@@ -69,10 +69,10 @@\n #endif\n #ifdef UATOMIC_HAS_ATOMIC_SHORT\n \tcase 2:\n-\t\treturn __sync_val_compare_and_swap_2(addr, old, _new);\n+\t\treturn __sync_val_compare_and_swap_2((uint16_t*) addr, old, _new);\n #endif\n \tcase 4:\n-\t\treturn __sync_val_compare_and_swap_4(addr, old, _new);\n+\t\treturn __sync_val_compare_and_swap_4((uint32_t*) addr, old, _new);\n #if (CAA_BITS_PER_LONG == 64)\n \tcase 8:\n \t\treturn __sync_val_compare_and_swap_8(addr, old, _new);\n@@ -109,7 +109,7 @@\n \t\treturn;\n #endif\n \tcase 4:\n-\t\t__sync_and_and_fetch_4(addr, val);\n+\t\t__sync_and_and_fetch_4((uint32_t*) addr, val);\n \t\treturn;\n #if (CAA_BITS_PER_LONG == 64)\n \tcase 8:\n@@ -148,7 +148,7 @@\n \t\treturn;\n #endif\n \tcase 4:\n-\t\t__sync_or_and_fetch_4(addr, val);\n+\t\t__sync_or_and_fetch_4((uint32_t*) addr, val);\n \t\treturn;\n #if (CAA_BITS_PER_LONG == 64)\n \tcase 8:\n@@ -187,7 +187,7 @@\n \t\treturn __sync_add_and_fetch_2(addr, val);\n #endif\n \tcase 4:\n-\t\treturn __sync_add_and_fetch_4(addr, val);\n+\t\treturn __sync_add_and_fetch_4((uint32_t*) addr, val);\n #if (CAA_BITS_PER_LONG == 64)\n \tcase 8:\n \t\treturn __sync_add_and_fetch_8(addr, val);\n"
  },
  {
    "path": "eng/common/cross/armel/tizen/tizen.patch",
    "content": "diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so\n--- a/usr/lib/libc.so\t2016-12-30 23:00:08.284951863 +0900\n+++ b/usr/lib/libc.so\t2016-12-30 23:00:32.140951815 +0900\n@@ -2,4 +2,4 @@\n    Use the shared library, but some functions are only in\n    the static library, so try that secondarily.  */\n OUTPUT_FORMAT(elf32-littlearm)\n-GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux.so.3 ) )\n+GROUP ( libc.so.6 libc_nonshared.a  AS_NEEDED ( ld-linux.so.3 ) )\n"
  },
  {
    "path": "eng/common/cross/build-android-rootfs.sh",
    "content": "#!/usr/bin/env bash\nset -e\n__NDK_Version=r21\n\nusage()\n{\n    echo \"Creates a toolchain and sysroot used for cross-compiling for Android.\"\n    echo\n    echo \"Usage: $0 [BuildArch] [ApiLevel] [--ndk NDKVersion]\"\n    echo\n    echo \"BuildArch is the target architecture of Android. Currently only arm64 is supported.\"\n    echo \"ApiLevel is the target Android API level. API levels usually match to Android releases. See https://source.android.com/source/build-numbers.html\"\n    echo \"NDKVersion is the version of Android NDK. The default is r21. See https://developer.android.com/ndk/downloads/revision_history\"\n    echo\n    echo \"By default, the toolchain and sysroot will be generated in cross/android-rootfs/toolchain/[BuildArch]. You can change this behavior\"\n    echo \"by setting the TOOLCHAIN_DIR environment variable\"\n    echo\n    echo \"By default, the NDK will be downloaded into the cross/android-rootfs/android-ndk-$__NDK_Version directory. If you already have an NDK installation,\"\n    echo \"you can set the NDK_DIR environment variable to have this script use that installation of the NDK.\"\n    echo \"By default, this script will generate a file, android_platform, in the root of the ROOTFS_DIR directory that contains the RID for the supported and tested Android build: android.28-arm64. This file is to replace '/etc/os-release', which is not available for Android.\"\n    exit 1\n}\n\n__ApiLevel=28 # The minimum platform for arm64 is API level 21 but the minimum version that support glob(3) is 28. See $ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/glob.h\n__BuildArch=arm64\n__AndroidArch=aarch64\n__AndroidToolchain=aarch64-linux-android\n\nwhile :; do\n    if [[ \"$#\" -le 0 ]]; then\n        break\n    fi\n\n    i=$1\n\n    lowerI=\"$(echo $i | tr \"[:upper:]\" \"[:lower:]\")\"\n    case $lowerI in\n        -?|-h|--help)\n            usage\n            exit 1\n            ;;\n        arm64)\n            __BuildArch=arm64\n            __AndroidArch=aarch64\n            __AndroidToolchain=aarch64-linux-android\n            ;;\n        arm)\n            __BuildArch=arm\n            __AndroidArch=arm\n            __AndroidToolchain=arm-linux-androideabi\n            ;;\n        --ndk)\n            shift\n            __NDK_Version=$1\n            ;;\n        *[0-9])\n            __ApiLevel=$i\n            ;;\n        *)\n            __UnprocessedBuildArgs=\"$__UnprocessedBuildArgs $i\"\n            ;;\n    esac\n    shift\ndone\n\nif [[ \"$__NDK_Version\" == \"r21\" ]] || [[ \"$__NDK_Version\" == \"r22\" ]]; then\n    __NDK_File_Arch_Spec=-x86_64\n    __SysRoot=sysroot\nelse\n    __NDK_File_Arch_Spec=\n    __SysRoot=toolchains/llvm/prebuilt/linux-x86_64/sysroot\nfi\n\n# Obtain the location of the bash script to figure out where the root of the repo is.\n__ScriptBaseDir=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\n\n__CrossDir=\"$__ScriptBaseDir/../../../.tools/android-rootfs\"\n\nif [[ ! -f \"$__CrossDir\" ]]; then\n    mkdir -p \"$__CrossDir\"\nfi\n\n# Resolve absolute path to avoid `../` in build logs\n__CrossDir=\"$( cd \"$__CrossDir\" && pwd )\"\n\n__NDK_Dir=\"$__CrossDir/android-ndk-$__NDK_Version\"\n__lldb_Dir=\"$__CrossDir/lldb\"\n__ToolchainDir=\"$__CrossDir/android-ndk-$__NDK_Version\"\n\nif [[ -n \"$TOOLCHAIN_DIR\" ]]; then\n    __ToolchainDir=$TOOLCHAIN_DIR\nfi\n\nif [[ -n \"$NDK_DIR\" ]]; then\n    __NDK_Dir=$NDK_DIR\nfi\n\necho \"Target API level: $__ApiLevel\"\necho \"Target architecture: $__BuildArch\"\necho \"NDK version: $__NDK_Version\"\necho \"NDK location: $__NDK_Dir\"\necho \"Target Toolchain location: $__ToolchainDir\"\n\n# Download the NDK if required\nif [ ! -d $__NDK_Dir ]; then\n    echo Downloading the NDK into $__NDK_Dir\n    mkdir -p $__NDK_Dir\n    wget -q --progress=bar:force:noscroll --show-progress https://dl.google.com/android/repository/android-ndk-$__NDK_Version-linux$__NDK_File_Arch_Spec.zip -O $__CrossDir/android-ndk-$__NDK_Version-linux.zip\n    unzip -q $__CrossDir/android-ndk-$__NDK_Version-linux.zip -d $__CrossDir\nfi\n\nif [ ! -d $__lldb_Dir ]; then\n    mkdir -p $__lldb_Dir\n    echo Downloading LLDB into $__lldb_Dir\n    wget -q --progress=bar:force:noscroll --show-progress https://dl.google.com/android/repository/lldb-2.3.3614996-linux-x86_64.zip -O $__CrossDir/lldb-2.3.3614996-linux-x86_64.zip\n    unzip -q $__CrossDir/lldb-2.3.3614996-linux-x86_64.zip -d $__lldb_Dir\nfi\n\necho \"Download dependencies...\"\n__TmpDir=$__CrossDir/tmp/$__BuildArch/\nmkdir -p \"$__TmpDir\"\n\n# combined dependencies for coreclr, installer and libraries\n__AndroidPackages=\"libicu\"\n__AndroidPackages+=\" libandroid-glob\"\n__AndroidPackages+=\" liblzma\"\n__AndroidPackages+=\" krb5\"\n__AndroidPackages+=\" openssl\"\n\nfor path in $(wget -qO- https://packages.termux.dev/termux-main-21/dists/stable/main/binary-$__AndroidArch/Packages |\\\n    grep -A15 \"Package: \\(${__AndroidPackages// /\\\\|}\\)\" | grep -v \"static\\|tool\" | grep Filename); do\n\n    if [[ \"$path\" != \"Filename:\" ]]; then\n        echo \"Working on: $path\"\n        wget -qO- https://packages.termux.dev/termux-main-21/$path | dpkg -x - \"$__TmpDir\"\n    fi\ndone\n\ncp -R \"$__TmpDir/data/data/com.termux/files/usr/\"* \"$__ToolchainDir/$__SysRoot/usr/\"\n\n# Generate platform file for build.sh script to assign to __DistroRid\necho \"Generating platform file...\"\necho \"RID=android.${__ApiLevel}-${__BuildArch}\" > $__ToolchainDir/$__SysRoot/android_platform\n\necho \"Now to build coreclr, libraries and host; run:\"\necho ROOTFS_DIR=$(realpath $__ToolchainDir/$__SysRoot) ./build.sh clr+libs+host --cross --arch $__BuildArch\n"
  },
  {
    "path": "eng/common/cross/build-rootfs.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nusage()\n{\n    echo \"Usage: $0 [BuildArch] [CodeName] [lldbx.y] [llvmx[.y]] [--skipunmount] --rootfsdir <directory>]\"\n    echo \"BuildArch can be: arm(default), arm64, armel, armv6, loongarch64, ppc64le, riscv64, s390x, x64, x86\"\n    echo \"CodeName - optional, Code name for Linux, can be: xenial(default), zesty, bionic, alpine\"\n    echo \"                               for alpine can be specified with version: alpineX.YY or alpineedge\"\n    echo \"                               for FreeBSD can be: freebsd13, freebsd14\"\n    echo \"                               for illumos can be: illumos\"\n    echo \"                               for Haiku can be: haiku.\"\n    echo \"lldbx.y - optional, LLDB version, can be: lldb3.9(default), lldb4.0, lldb5.0, lldb6.0 no-lldb. Ignored for alpine and FreeBSD\"\n    echo \"llvmx[.y] - optional, LLVM version for LLVM related packages.\"\n    echo \"--skipunmount - optional, will skip the unmount of rootfs folder.\"\n    echo \"--skipsigcheck - optional, will skip package signature checks (allowing untrusted packages).\"\n    echo \"--skipemulation - optional, will skip qemu and debootstrap requirement when building environment for debian based systems.\"\n    echo \"--use-mirror - optional, use mirror URL to fetch resources, when available.\"\n    echo \"--jobs N - optional, restrict to N jobs.\"\n    exit 1\n}\n\n__CodeName=xenial\n__CrossDir=$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\n__BuildArch=arm\n__AlpineArch=armv7\n__FreeBSDArch=arm\n__FreeBSDMachineArch=armv7\n__IllumosArch=arm7\n__HaikuArch=arm\n__QEMUArch=arm\n__UbuntuArch=armhf\n__UbuntuRepo=\n__UbuntuSuites=\"updates security backports\"\n__DebianSuites=\n__LLDB_Package=\"liblldb-3.9-dev\"\n__SkipUnmount=0\n\n# base development support\n__UbuntuPackages=\"build-essential\"\n\n__AlpinePackages=\"alpine-base\"\n__AlpinePackages+=\" build-base\"\n__AlpinePackages+=\" linux-headers\"\n__AlpinePackages+=\" lldb-dev\"\n__AlpinePackages+=\" python3\"\n__AlpinePackages+=\" libedit\"\n\n# symlinks fixer\n__UbuntuPackages+=\" symlinks\"\n\n# runtime dependencies\n__UbuntuPackages+=\" libicu-dev\"\n__UbuntuPackages+=\" liblttng-ust-dev\"\n__UbuntuPackages+=\" libunwind8-dev\"\n\n__AlpinePackages+=\" gettext-dev\"\n__AlpinePackages+=\" icu-dev\"\n__AlpinePackages+=\" libunwind-dev\"\n__AlpinePackages+=\" lttng-ust-dev\"\n__AlpinePackages+=\" compiler-rt\"\n\n# runtime libraries' dependencies\n__UbuntuPackages+=\" libcurl4-openssl-dev\"\n__UbuntuPackages+=\" libkrb5-dev\"\n__UbuntuPackages+=\" libssl-dev\"\n__UbuntuPackages+=\" zlib1g-dev\"\n__UbuntuPackages+=\" libbrotli-dev\"\n\n__AlpinePackages+=\" curl-dev\"\n__AlpinePackages+=\" krb5-dev\"\n__AlpinePackages+=\" openssl-dev\"\n__AlpinePackages+=\" zlib-dev\"\n\n__FreeBSDBase=\"13.4-RELEASE\"\n__FreeBSDPkg=\"1.21.3\"\n__FreeBSDABI=\"13\"\n__FreeBSDPackages=\"libunwind\"\n__FreeBSDPackages+=\" icu\"\n__FreeBSDPackages+=\" libinotify\"\n__FreeBSDPackages+=\" openssl\"\n__FreeBSDPackages+=\" krb5\"\n__FreeBSDPackages+=\" terminfo-db\"\n\n__IllumosPackages=\"icu\"\n__IllumosPackages+=\" mit-krb5\"\n__IllumosPackages+=\" openssl\"\n__IllumosPackages+=\" zlib\"\n\n__HaikuPackages=\"gcc_syslibs\"\n__HaikuPackages+=\" gcc_syslibs_devel\"\n__HaikuPackages+=\" gmp\"\n__HaikuPackages+=\" gmp_devel\"\n__HaikuPackages+=\" icu[0-9]+\"\n__HaikuPackages+=\" icu[0-9]*_devel\"\n__HaikuPackages+=\" krb5\"\n__HaikuPackages+=\" krb5_devel\"\n__HaikuPackages+=\" libiconv\"\n__HaikuPackages+=\" libiconv_devel\"\n__HaikuPackages+=\" llvm[0-9]*_libunwind\"\n__HaikuPackages+=\" llvm[0-9]*_libunwind_devel\"\n__HaikuPackages+=\" mpfr\"\n__HaikuPackages+=\" mpfr_devel\"\n__HaikuPackages+=\" openssl3\"\n__HaikuPackages+=\" openssl3_devel\"\n__HaikuPackages+=\" zlib\"\n__HaikuPackages+=\" zlib_devel\"\n\n# ML.NET dependencies\n__UbuntuPackages+=\" libomp5\"\n__UbuntuPackages+=\" libomp-dev\"\n\n# Taken from https://github.com/alpinelinux/alpine-chroot-install/blob/6d08f12a8a70dd9b9dc7d997c88aa7789cc03c42/alpine-chroot-install#L85-L133\n__AlpineKeys='\n4a6a0840:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1yHJxQgsHQREclQu4Ohe\\nqxTxd1tHcNnvnQTu/UrTky8wWvgXT+jpveroeWWnzmsYlDI93eLI2ORakxb3gA2O\\nQ0Ry4ws8vhaxLQGC74uQR5+/yYrLuTKydFzuPaS1dK19qJPXB8GMdmFOijnXX4SA\\njixuHLe1WW7kZVtjL7nufvpXkWBGjsfrvskdNA/5MfxAeBbqPgaq0QMEfxMAn6/R\\nL5kNepi/Vr4S39Xvf2DzWkTLEK8pcnjNkt9/aafhWqFVW7m3HCAII6h/qlQNQKSo\\nGuH34Q8GsFG30izUENV9avY7hSLq7nggsvknlNBZtFUcmGoQrtx3FmyYsIC8/R+B\\nywIDAQAB\n5243ef4b:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvNijDxJ8kloskKQpJdx+\\nmTMVFFUGDoDCbulnhZMJoKNkSuZOzBoFC94omYPtxnIcBdWBGnrm6ncbKRlR+6oy\\nDO0W7c44uHKCFGFqBhDasdI4RCYP+fcIX/lyMh6MLbOxqS22TwSLhCVjTyJeeH7K\\naA7vqk+QSsF4TGbYzQDDpg7+6aAcNzg6InNePaywA6hbT0JXbxnDWsB+2/LLSF2G\\nmnhJlJrWB1WGjkz23ONIWk85W4S0XB/ewDefd4Ly/zyIciastA7Zqnh7p3Ody6Q0\\nsS2MJzo7p3os1smGjUF158s6m/JbVh4DN6YIsxwl2OjDOz9R0OycfJSDaBVIGZzg\\ncQIDAQAB\n524d27bb:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr8s1q88XpuJWLCZALdKj\\nlN8wg2ePB2T9aIcaxryYE/Jkmtu+ZQ5zKq6BT3y/udt5jAsMrhHTwroOjIsF9DeG\\ne8Y3vjz+Hh4L8a7hZDaw8jy3CPag47L7nsZFwQOIo2Cl1SnzUc6/owoyjRU7ab0p\\niWG5HK8IfiybRbZxnEbNAfT4R53hyI6z5FhyXGS2Ld8zCoU/R4E1P0CUuXKEN4p0\\n64dyeUoOLXEWHjgKiU1mElIQj3k/IF02W89gDj285YgwqA49deLUM7QOd53QLnx+\\nxrIrPv3A+eyXMFgexNwCKQU9ZdmWa00MjjHlegSGK8Y2NPnRoXhzqSP9T9i2HiXL\\nVQIDAQAB\n5261cecb:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwlzMkl7b5PBdfMzGdCT0\\ncGloRr5xGgVmsdq5EtJvFkFAiN8Ac9MCFy/vAFmS8/7ZaGOXoCDWbYVLTLOO2qtX\\nyHRl+7fJVh2N6qrDDFPmdgCi8NaE+3rITWXGrrQ1spJ0B6HIzTDNEjRKnD4xyg4j\\ng01FMcJTU6E+V2JBY45CKN9dWr1JDM/nei/Pf0byBJlMp/mSSfjodykmz4Oe13xB\\nCa1WTwgFykKYthoLGYrmo+LKIGpMoeEbY1kuUe04UiDe47l6Oggwnl+8XD1MeRWY\\nsWgj8sF4dTcSfCMavK4zHRFFQbGp/YFJ/Ww6U9lA3Vq0wyEI6MCMQnoSMFwrbgZw\\nwwIDAQAB\n58199dcc:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3v8/ye/V/t5xf4JiXLXa\\nhWFRozsnmn3hobON20GdmkrzKzO/eUqPOKTpg2GtvBhK30fu5oY5uN2ORiv2Y2ht\\neLiZ9HVz3XP8Fm9frha60B7KNu66FO5P2o3i+E+DWTPqqPcCG6t4Znk2BypILcit\\nwiPKTsgbBQR2qo/cO01eLLdt6oOzAaF94NH0656kvRewdo6HG4urbO46tCAizvCR\\nCA7KGFMyad8WdKkTjxh8YLDLoOCtoZmXmQAiwfRe9pKXRH/XXGop8SYptLqyVVQ+\\ntegOD9wRs2tOlgcLx4F/uMzHN7uoho6okBPiifRX+Pf38Vx+ozXh056tjmdZkCaV\\naQIDAQAB\n58cbb476:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoSPnuAGKtRIS5fEgYPXD\\n8pSGvKAmIv3A08LBViDUe+YwhilSHbYXUEAcSH1KZvOo1WT1x2FNEPBEFEFU1Eyc\\n+qGzbA03UFgBNvArurHQ5Z/GngGqE7IarSQFSoqewYRtFSfp+TL9CUNBvM0rT7vz\\n2eMu3/wWG+CBmb92lkmyWwC1WSWFKO3x8w+Br2IFWvAZqHRt8oiG5QtYvcZL6jym\\nY8T6sgdDlj+Y+wWaLHs9Fc+7vBuyK9C4O1ORdMPW15qVSl4Lc2Wu1QVwRiKnmA+c\\nDsH/m7kDNRHM7TjWnuj+nrBOKAHzYquiu5iB3Qmx+0gwnrSVf27Arc3ozUmmJbLj\\nzQIDAQAB\n58e4f17d:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvBxJN9ErBgdRcPr5g4hV\\nqyUSGZEKuvQliq2Z9SRHLh2J43+EdB6A+yzVvLnzcHVpBJ+BZ9RV30EM9guck9sh\\nr+bryZcRHyjG2wiIEoduxF2a8KeWeQH7QlpwGhuobo1+gA8L0AGImiA6UP3LOirl\\nI0G2+iaKZowME8/tydww4jx5vG132JCOScMjTalRsYZYJcjFbebQQolpqRaGB4iG\\nWqhytWQGWuKiB1A22wjmIYf3t96l1Mp+FmM2URPxD1gk/BIBnX7ew+2gWppXOK9j\\n1BJpo0/HaX5XoZ/uMqISAAtgHZAqq+g3IUPouxTphgYQRTRYpz2COw3NF43VYQrR\\nbQIDAQAB\n60ac2099:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwR4uJVtJOnOFGchnMW5Y\\nj5/waBdG1u5BTMlH+iQMcV5+VgWhmpZHJCBz3ocD+0IGk2I68S5TDOHec/GSC0lv\\n6R9o6F7h429GmgPgVKQsc8mPTPtbjJMuLLs4xKc+viCplXc0Nc0ZoHmCH4da6fCV\\ntdpHQjVe6F9zjdquZ4RjV6R6JTiN9v924dGMAkbW/xXmamtz51FzondKC52Gh8Mo\\n/oA0/T0KsCMCi7tb4QNQUYrf+Xcha9uus4ww1kWNZyfXJB87a2kORLiWMfs2IBBJ\\nTmZ2Fnk0JnHDb8Oknxd9PvJPT0mvyT8DA+KIAPqNvOjUXP4bnjEHJcoCP9S5HkGC\\nIQIDAQAB\n6165ee59:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAutQkua2CAig4VFSJ7v54\\nALyu/J1WB3oni7qwCZD3veURw7HxpNAj9hR+S5N/pNeZgubQvJWyaPuQDm7PTs1+\\ntFGiYNfAsiibX6Rv0wci3M+z2XEVAeR9Vzg6v4qoofDyoTbovn2LztaNEjTkB+oK\\ntlvpNhg1zhou0jDVYFniEXvzjckxswHVb8cT0OMTKHALyLPrPOJzVtM9C1ew2Nnc\\n3848xLiApMu3NBk0JqfcS3Bo5Y2b1FRVBvdt+2gFoKZix1MnZdAEZ8xQzL/a0YS5\\nHd0wj5+EEKHfOd3A75uPa/WQmA+o0cBFfrzm69QDcSJSwGpzWrD1ScH3AK8nWvoj\\nv7e9gukK/9yl1b4fQQ00vttwJPSgm9EnfPHLAtgXkRloI27H6/PuLoNvSAMQwuCD\\nhQRlyGLPBETKkHeodfLoULjhDi1K2gKJTMhtbnUcAA7nEphkMhPWkBpgFdrH+5z4\\nLxy+3ek0cqcI7K68EtrffU8jtUj9LFTUC8dERaIBs7NgQ/LfDbDfGh9g6qVj1hZl\\nk9aaIPTm/xsi8v3u+0qaq7KzIBc9s59JOoA8TlpOaYdVgSQhHHLBaahOuAigH+VI\\nisbC9vmqsThF2QdDtQt37keuqoda2E6sL7PUvIyVXDRfwX7uMDjlzTxHTymvq2Ck\\nhtBqojBnThmjJQFgZXocHG8CAwEAAQ==\n61666e3f:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlEyxkHggKCXC2Wf5Mzx4\\nnZLFZvU2bgcA3exfNPO/g1YunKfQY+Jg4fr6tJUUTZ3XZUrhmLNWvpvSwDS19ZmC\\nIXOu0+V94aNgnhMsk9rr59I8qcbsQGIBoHzuAl8NzZCgdbEXkiY90w1skUw8J57z\\nqCsMBydAueMXuWqF5nGtYbi5vHwK42PffpiZ7G5Kjwn8nYMW5IZdL6ZnMEVJUWC9\\nI4waeKg0yskczYDmZUEAtrn3laX9677ToCpiKrvmZYjlGl0BaGp3cxggP2xaDbUq\\nqfFxWNgvUAb3pXD09JM6Mt6HSIJaFc9vQbrKB9KT515y763j5CC2KUsilszKi3mB\\nHYe5PoebdjS7D1Oh+tRqfegU2IImzSwW3iwA7PJvefFuc/kNIijfS/gH/cAqAK6z\\nbhdOtE/zc7TtqW2Wn5Y03jIZdtm12CxSxwgtCF1NPyEWyIxAQUX9ACb3M0FAZ61n\\nfpPrvwTaIIxxZ01L3IzPLpbc44x/DhJIEU+iDt6IMTrHOphD9MCG4631eIdB0H1b\\n6zbNX1CXTsafqHRFV9XmYYIeOMggmd90s3xIbEujA6HKNP/gwzO6CDJ+nHFDEqoF\\nSkxRdTkEqjTjVKieURW7Swv7zpfu5PrsrrkyGnsRrBJJzXlm2FOOxnbI2iSL1B5F\\nrO5kbUxFeZUIDq+7Yv4kLWcCAwEAAQ==\n616a9724:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnC+bR4bHf/L6QdU4puhQ\\ngl1MHePszRC38bzvVFDUJsmCaMCL2suCs2A2yxAgGb9pu9AJYLAmxQC4mM3jNqhg\\n/E7yuaBbek3O02zN/ctvflJ250wZCy+z0ZGIp1ak6pu1j14IwHokl9j36zNfGtfv\\nADVOcdpWITFFlPqwq1qt/H3UsKVmtiF3BNWWTeUEQwKvlU8ymxgS99yn0+4OPyNT\\nL3EUeS+NQJtDS01unau0t7LnjUXn+XIneWny8bIYOQCuVR6s/gpIGuhBaUqwaJOw\\n7jkJZYF2Ij7uPb4b5/R3vX2FfxxqEHqssFSg8FFUNTZz3qNZs0CRVyfA972g9WkJ\\nhPfn31pQYil4QGRibCMIeU27YAEjXoqfJKEPh4UWMQsQLrEfdGfb8VgwrPbniGfU\\nL3jKJR3VAafL9330iawzVQDlIlwGl6u77gEXMl9K0pfazunYhAp+BMP+9ot5ckK+\\nosmrqj11qMESsAj083GeFdfV3pXEIwUytaB0AKEht9DbqUfiE/oeZ/LAXgySMtVC\\nsbC4ESmgVeY2xSBIJdDyUap7FR49GGrw0W49NUv9gRgQtGGaNVQQO9oGL2PBC41P\\niWF9GLoX30HIz1P8PF/cZvicSSPkQf2Z6TV+t0ebdGNS5DjapdnCrq8m9Z0pyKsQ\\nuxAL2a7zX8l5i1CZh1ycUGsCAwEAAQ==\n616abc23:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0MfCDrhODRCIxR9Dep1s\\neXafh5CE5BrF4WbCgCsevyPIdvTeyIaW4vmO3bbG4VzhogDZju+R3IQYFuhoXP5v\\nY+zYJGnwrgz3r5wYAvPnLEs1+dtDKYOgJXQj+wLJBW1mzRDL8FoRXOe5iRmn1EFS\\nwZ1DoUvyu7/J5r0itKicZp3QKED6YoilXed+1vnS4Sk0mzN4smuMR9eO1mMCqNp9\\n9KTfRDHTbakIHwasECCXCp50uXdoW6ig/xUAFanpm9LtK6jctNDbXDhQmgvAaLXZ\\nLvFqoaYJ/CvWkyYCgL6qxvMvVmPoRv7OPcyni4xR/WgWa0MSaEWjgPx3+yj9fiMA\\n1S02pFWFDOr5OUF/O4YhFJvUCOtVsUPPfA/Lj6faL0h5QI9mQhy5Zb9TTaS9jB6p\\nLw7u0dJlrjFedk8KTJdFCcaGYHP6kNPnOxMylcB/5WcztXZVQD5WpCicGNBxCGMm\\nW64SgrV7M07gQfL/32QLsdqPUf0i8hoVD8wfQ3EpbQzv6Fk1Cn90bZqZafg8XWGY\\nwddhkXk7egrr23Djv37V2okjzdqoyLBYBxMz63qQzFoAVv5VoY2NDTbXYUYytOvG\\nGJ1afYDRVWrExCech1mX5ZVUB1br6WM+psFLJFoBFl6mDmiYt0vMYBddKISsvwLl\\nIJQkzDwtXzT2cSjoj3T5QekCAwEAAQ==\n616ac3bc:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvaaoSLab+IluixwKV5Od\\n0gib2YurjPatGIbn5Ov2DLUFYiebj2oJINXJSwUOO+4WcuHFEqiL/1rya+k5hLZt\\nhnPL1tn6QD4rESznvGSasRCQNT2vS/oyZbTYJRyAtFkEYLlq0t3S3xBxxHWuvIf0\\nqVxVNYpQWyM3N9RIeYBR/euXKJXileSHk/uq1I5wTC0XBIHWcthczGN0m9wBEiWS\\n0m3cnPk4q0Ea8mUJ91Rqob19qETz6VbSPYYpZk3qOycjKosuwcuzoMpwU8KRiMFd\\n5LHtX0Hx85ghGsWDVtS0c0+aJa4lOMGvJCAOvDfqvODv7gKlCXUpgumGpLdTmaZ8\\n1RwqspAe3IqBcdKTqRD4m2mSg23nVx2FAY3cjFvZQtfooT7q1ItRV5RgH6FhQSl7\\n+6YIMJ1Bf8AAlLdRLpg+doOUGcEn+pkDiHFgI8ylH1LKyFKw+eXaAml/7DaWZk1d\\ndqggwhXOhc/UUZFQuQQ8A8zpA13PcbC05XxN2hyP93tCEtyynMLVPtrRwDnHxFKa\\nqKzs3rMDXPSXRn3ZZTdKH3069ApkEjQdpcwUh+EmJ1Ve/5cdtzT6kKWCjKBFZP/s\\n91MlRrX2BTRdHaU5QJkUheUtakwxuHrdah2F94lRmsnQlpPr2YseJu6sIE+Dnx4M\\nCfhdVbQL2w54R645nlnohu8CAwEAAQ==\n616adfeb:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq0BFD1D4lIxQcsqEpQzU\\npNCYM3aP1V/fxxVdT4DWvSI53JHTwHQamKdMWtEXetWVbP5zSROniYKFXd/xrD9X\\n0jiGHey3lEtylXRIPxe5s+wXoCmNLcJVnvTcDtwx/ne2NLHxp76lyc25At+6RgE6\\nADjLVuoD7M4IFDkAsd8UQ8zM0Dww9SylIk/wgV3ZkifecvgUQRagrNUdUjR56EBZ\\nraQrev4hhzOgwelT0kXCu3snbUuNY/lU53CoTzfBJ5UfEJ5pMw1ij6X0r5S9IVsy\\nKLWH1hiO0NzU2c8ViUYCly4Fe9xMTFc6u2dy/dxf6FwERfGzETQxqZvSfrRX+GLj\\n/QZAXiPg5178hT/m0Y3z5IGenIC/80Z9NCi+byF1WuJlzKjDcF/TU72zk0+PNM/H\\nKuppf3JT4DyjiVzNC5YoWJT2QRMS9KLP5iKCSThwVceEEg5HfhQBRT9M6KIcFLSs\\nmFjx9kNEEmc1E8hl5IR3+3Ry8G5/bTIIruz14jgeY9u5jhL8Vyyvo41jgt9sLHR1\\n/J1TxKfkgksYev7PoX6/ZzJ1ksWKZY5NFoDXTNYUgzFUTOoEaOg3BAQKadb3Qbbq\\nXIrxmPBdgrn9QI7NCgfnAY3Tb4EEjs3ON/BNyEhUENcXOH6I1NbcuBQ7g9P73kE4\\nVORdoc8MdJ5eoKBpO8Ww8HECAwEAAQ==\n616ae350:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyduVzi1mWm+lYo2Tqt/0\\nXkCIWrDNP1QBMVPrE0/ZlU2bCGSoo2Z9FHQKz/mTyMRlhNqTfhJ5qU3U9XlyGOPJ\\npiM+b91g26pnpXJ2Q2kOypSgOMOPA4cQ42PkHBEqhuzssfj9t7x47ppS94bboh46\\nxLSDRff/NAbtwTpvhStV3URYkxFG++cKGGa5MPXBrxIp+iZf9GnuxVdST5PGiVGP\\nODL/b69sPJQNbJHVquqUTOh5Ry8uuD2WZuXfKf7/C0jC/ie9m2+0CttNu9tMciGM\\nEyKG1/Xhk5iIWO43m4SrrT2WkFlcZ1z2JSf9Pjm4C2+HovYpihwwdM/OdP8Xmsnr\\nDzVB4YvQiW+IHBjStHVuyiZWc+JsgEPJzisNY0Wyc/kNyNtqVKpX6dRhMLanLmy+\\nf53cCSI05KPQAcGj6tdL+D60uKDkt+FsDa0BTAobZ31OsFVid0vCXtsbplNhW1IF\\nHwsGXBTVcfXg44RLyL8Lk/2dQxDHNHzAUslJXzPxaHBLmt++2COa2EI1iWlvtznk\\nOk9WP8SOAIj+xdqoiHcC4j72BOVVgiITIJNHrbppZCq6qPR+fgXmXa+sDcGh30m6\\n9Wpbr28kLMSHiENCWTdsFij+NQTd5S47H7XTROHnalYDuF1RpS+DpQidT5tUimaT\\nJZDr++FjKrnnijbyNF8b98UCAwEAAQ==\n616db30d:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpUpyWDWjlUk3smlWeA0\\nlIMW+oJ38t92CRLHH3IqRhyECBRW0d0aRGtq7TY8PmxjjvBZrxTNDpJT6KUk4LRm\\na6A6IuAI7QnNK8SJqM0DLzlpygd7GJf8ZL9SoHSH+gFsYF67Cpooz/YDqWrlN7Vw\\ntO00s0B+eXy+PCXYU7VSfuWFGK8TGEv6HfGMALLjhqMManyvfp8hz3ubN1rK3c8C\\nUS/ilRh1qckdbtPvoDPhSbTDmfU1g/EfRSIEXBrIMLg9ka/XB9PvWRrekrppnQzP\\nhP9YE3x/wbFc5QqQWiRCYyQl/rgIMOXvIxhkfe8H5n1Et4VAorkpEAXdsfN8KSVv\\nLSMazVlLp9GYq5SUpqYX3KnxdWBgN7BJoZ4sltsTpHQ/34SXWfu3UmyUveWj7wp0\\nx9hwsPirVI00EEea9AbP7NM2rAyu6ukcm4m6ATd2DZJIViq2es6m60AE6SMCmrQF\\nwmk4H/kdQgeAELVfGOm2VyJ3z69fQuywz7xu27S6zTKi05Qlnohxol4wVb6OB7qG\\nLPRtK9ObgzRo/OPumyXqlzAi/Yvyd1ZQk8labZps3e16bQp8+pVPiumWioMFJDWV\\nGZjCmyMSU8V6MB6njbgLHoyg2LCukCAeSjbPGGGYhnKLm1AKSoJh3IpZuqcKCk5C\\n8CM1S15HxV78s9dFntEqIokCAwEAAQ==\n66ba20fe:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtfB12w4ZgqsXWZDfUAV/\\n6Y4aHUKIu3q4SXrNZ7CXF9nXoAVYrS7NAxJdAodsY3vPCN0g5O8DFXR+390LdOuQ\\n+HsGKCc1k5tX5ZXld37EZNTNSbR0k+NKhd9h6X3u6wqPOx7SIKxwAQR8qeeFq4pP\\nrt9GAGlxtuYgzIIcKJPwE0dZlcBCg+GnptCUZXp/38BP1eYC+xTXSL6Muq1etYfg\\nodXdb7Yl+2h1IHuOwo5rjgY5kpY7GcAs8AjGk3lDD/av60OTYccknH0NCVSmPoXK\\nvrxDBOn0LQRNBLcAfnTKgHrzy0Q5h4TNkkyTgxkoQw5ObDk9nnabTxql732yy9BY\\ns+hM9+dSFO1HKeVXreYSA2n1ndF18YAvAumzgyqzB7I4pMHXq1kC/8bONMJxwSkS\\nYm6CoXKyavp7RqGMyeVpRC7tV+blkrrUml0BwNkxE+XnwDRB3xDV6hqgWe0XrifD\\nYTfvd9ScZQP83ip0r4IKlq4GMv/R5shcCRJSkSZ6QSGshH40JYSoiwJf5FHbj9ND\\n7do0UAqebWo4yNx63j/wb2ULorW3AClv0BCFSdPsIrCStiGdpgJDBR2P2NZOCob3\\nG9uMj+wJD6JJg2nWqNJxkANXX37Qf8plgzssrhrgOvB0fjjS7GYhfkfmZTJ0wPOw\\nA8+KzFseBh4UFGgue78KwgkCAwEAAQ==\n'\n__Keyring=\n__KeyringFile=\"/usr/share/keyrings/ubuntu-archive-keyring.gpg\"\n__SkipSigCheck=0\n__SkipEmulation=0\n__UseMirror=0\n\n__UnprocessedBuildArgs=\nwhile :; do\n    if [[ \"$#\" -le 0 ]]; then\n        break\n    fi\n\n    lowerI=\"$(echo \"$1\" | tr \"[:upper:]\" \"[:lower:]\")\"\n    case $lowerI in\n        -\\?|-h|--help)\n            usage\n            ;;\n        arm)\n            __BuildArch=arm\n            __UbuntuArch=armhf\n            __AlpineArch=armv7\n            __QEMUArch=arm\n            ;;\n        arm64)\n            __BuildArch=arm64\n            __UbuntuArch=arm64\n            __AlpineArch=aarch64\n            __QEMUArch=aarch64\n            __FreeBSDArch=arm64\n            __FreeBSDMachineArch=aarch64\n            ;;\n        armel)\n            __BuildArch=armel\n            __UbuntuArch=armel\n            __UbuntuRepo=\"http://ftp.debian.org/debian/\"\n            __CodeName=jessie\n            __KeyringFile=\"/usr/share/keyrings/debian-archive-keyring.gpg\"\n            ;;\n        armv6)\n            __BuildArch=armv6\n            __UbuntuArch=armhf\n            __QEMUArch=arm\n            __UbuntuRepo=\"http://raspbian.raspberrypi.org/raspbian/\"\n            __CodeName=buster\n            __KeyringFile=\"/usr/share/keyrings/raspbian-archive-keyring.gpg\"\n            __LLDB_Package=\"liblldb-6.0-dev\"\n            __UbuntuSuites=\n\n            if [[ -e \"$__KeyringFile\" ]]; then\n                __Keyring=\"--keyring $__KeyringFile\"\n            fi\n            ;;\n        loongarch64)\n            __BuildArch=loongarch64\n            __AlpineArch=loongarch64\n            __QEMUArch=loongarch64\n            __UbuntuArch=loong64\n            __UbuntuSuites=\n            __DebianSuites=unreleased\n            __LLDB_Package=\"liblldb-19-dev\"\n\n            if [[ \"$__CodeName\" == \"sid\" ]]; then\n                __UbuntuRepo=\"http://ftp.ports.debian.org/debian-ports/\"\n            fi\n            ;;\n        riscv64)\n            __BuildArch=riscv64\n            __AlpineArch=riscv64\n            __AlpinePackages=\"${__AlpinePackages// lldb-dev/}\"\n            __QEMUArch=riscv64\n            __UbuntuArch=riscv64\n            __UbuntuPackages=\"${__UbuntuPackages// libunwind8-dev/}\"\n            unset __LLDB_Package\n            ;;\n        ppc64le)\n            __BuildArch=ppc64le\n            __AlpineArch=ppc64le\n            __QEMUArch=ppc64le\n            __UbuntuArch=ppc64el\n            __UbuntuRepo=\"http://ports.ubuntu.com/ubuntu-ports/\"\n            __UbuntuPackages=\"${__UbuntuPackages// libunwind8-dev/}\"\n            __UbuntuPackages=\"${__UbuntuPackages// libomp-dev/}\"\n            __UbuntuPackages=\"${__UbuntuPackages// libomp5/}\"\n            unset __LLDB_Package\n            ;;\n        s390x)\n            __BuildArch=s390x\n            __AlpineArch=s390x\n            __QEMUArch=s390x\n            __UbuntuArch=s390x\n            __UbuntuRepo=\"http://ports.ubuntu.com/ubuntu-ports/\"\n            __UbuntuPackages=\"${__UbuntuPackages// libunwind8-dev/}\"\n            __UbuntuPackages=\"${__UbuntuPackages// libomp-dev/}\"\n            __UbuntuPackages=\"${__UbuntuPackages// libomp5/}\"\n            unset __LLDB_Package\n            ;;\n        x64)\n            __BuildArch=x64\n            __AlpineArch=x86_64\n            __UbuntuArch=amd64\n            __FreeBSDArch=amd64\n            __FreeBSDMachineArch=amd64\n            __illumosArch=x86_64\n            __HaikuArch=x86_64\n            __UbuntuRepo=\"http://archive.ubuntu.com/ubuntu/\"\n            ;;\n        x86)\n            __BuildArch=x86\n            __UbuntuArch=i386\n            __AlpineArch=x86\n            __UbuntuRepo=\"http://archive.ubuntu.com/ubuntu/\"\n            ;;\n        lldb*)\n            version=\"$(echo \"$lowerI\" | tr -d '[:alpha:]-=')\"\n            majorVersion=\"${version%%.*}\"\n\n            [ -z \"${version##*.*}\" ] && minorVersion=\"${version#*.}\"\n            if [ -z \"$minorVersion\" ]; then\n                minorVersion=0\n            fi\n\n            # for versions > 6.0, lldb has dropped the minor version\n            if [ \"$majorVersion\" -le 6 ]; then\n                version=\"$majorVersion.$minorVersion\"\n            else\n                version=\"$majorVersion\"\n            fi\n\n            __LLDB_Package=\"liblldb-${version}-dev\"\n            ;;\n        no-lldb)\n            unset __LLDB_Package\n            ;;\n        llvm*)\n            version=\"$(echo \"$lowerI\" | tr -d '[:alpha:]-=')\"\n            __LLVM_MajorVersion=\"${version%%.*}\"\n\n            [ -z \"${version##*.*}\" ] && __LLVM_MinorVersion=\"${version#*.}\"\n            if [ -z \"$__LLVM_MinorVersion\" ]; then\n                __LLVM_MinorVersion=0\n            fi\n\n            # for versions > 6.0, lldb has dropped the minor version\n            if [ \"$__LLVM_MajorVersion\" -gt 6 ]; then\n                __LLVM_MinorVersion=\n            fi\n\n            ;;\n        xenial) # Ubuntu 16.04\n            if [[ \"$__CodeName\" != \"jessie\" ]]; then\n                __CodeName=xenial\n            fi\n            ;;\n        zesty) # Ubuntu 17.04\n            if [[ \"$__CodeName\" != \"jessie\" ]]; then\n                __CodeName=zesty\n            fi\n            ;;\n        bionic) # Ubuntu 18.04\n            if [[ \"$__CodeName\" != \"jessie\" ]]; then\n                __CodeName=bionic\n            fi\n            ;;\n        focal) # Ubuntu 20.04\n            if [[ \"$__CodeName\" != \"jessie\" ]]; then\n                __CodeName=focal\n            fi\n            ;;\n        jammy) # Ubuntu 22.04\n            if [[ \"$__CodeName\" != \"jessie\" ]]; then\n                __CodeName=jammy\n            fi\n            ;;\n        noble) # Ubuntu 24.04\n            if [[ \"$__CodeName\" != \"jessie\" ]]; then\n                __CodeName=noble\n            fi\n            if [[ -n \"$__LLDB_Package\" ]]; then\n                __LLDB_Package=\"liblldb-18-dev\"\n            fi\n            ;;\n        jessie) # Debian 8\n            __CodeName=jessie\n            __KeyringFile=\"/usr/share/keyrings/debian-archive-keyring.gpg\"\n\n            if [[ -z \"$__UbuntuRepo\" ]]; then\n                __UbuntuRepo=\"http://ftp.debian.org/debian/\"\n            fi\n            ;;\n        stretch) # Debian 9\n            __CodeName=stretch\n            __LLDB_Package=\"liblldb-6.0-dev\"\n            __KeyringFile=\"/usr/share/keyrings/debian-archive-keyring.gpg\"\n\n            if [[ -z \"$__UbuntuRepo\" ]]; then\n                __UbuntuRepo=\"http://ftp.debian.org/debian/\"\n            fi\n            ;;\n        buster) # Debian 10\n            __CodeName=buster\n            __LLDB_Package=\"liblldb-6.0-dev\"\n            __KeyringFile=\"/usr/share/keyrings/debian-archive-keyring.gpg\"\n\n            if [[ -z \"$__UbuntuRepo\" ]]; then\n                __UbuntuRepo=\"http://ftp.debian.org/debian/\"\n            fi\n            ;;\n        bullseye) # Debian 11\n            __CodeName=bullseye\n            __KeyringFile=\"/usr/share/keyrings/debian-archive-keyring.gpg\"\n\n            if [[ -z \"$__UbuntuRepo\" ]]; then\n                __UbuntuRepo=\"http://ftp.debian.org/debian/\"\n            fi\n            ;;\n        bookworm) # Debian 12\n            __CodeName=bookworm\n            __KeyringFile=\"/usr/share/keyrings/debian-archive-keyring.gpg\"\n\n            if [[ -z \"$__UbuntuRepo\" ]]; then\n                __UbuntuRepo=\"http://ftp.debian.org/debian/\"\n            fi\n            ;;\n        sid) # Debian sid\n            __CodeName=sid\n            __UbuntuSuites=\n\n            # Debian-Ports architectures need different values\n            case \"$__UbuntuArch\" in\n            amd64|arm64|armel|armhf|i386|mips64el|ppc64el|riscv64|s390x)\n                __KeyringFile=\"/usr/share/keyrings/debian-archive-keyring.gpg\"\n\n                if [[ -z \"$__UbuntuRepo\" ]]; then\n                    __UbuntuRepo=\"http://ftp.debian.org/debian/\"\n                fi\n                ;;\n            *)\n                __KeyringFile=\"/usr/share/keyrings/debian-ports-archive-keyring.gpg\"\n\n                if [[ -z \"$__UbuntuRepo\" ]]; then\n                    __UbuntuRepo=\"http://ftp.ports.debian.org/debian-ports/\"\n                fi\n                ;;\n            esac\n\n            if [[ -e \"$__KeyringFile\" ]]; then\n                __Keyring=\"--keyring $__KeyringFile\"\n            fi\n            ;;\n        tizen)\n            __CodeName=\n            __UbuntuRepo=\n            __Tizen=tizen\n            ;;\n        alpine*)\n            __CodeName=alpine\n            __UbuntuRepo=\n\n            if [[ \"$lowerI\" == \"alpineedge\" ]]; then\n                __AlpineVersion=edge\n            else\n                version=\"$(echo \"$lowerI\" | tr -d '[:alpha:]-=')\"\n                __AlpineMajorVersion=\"${version%%.*}\"\n                __AlpineMinorVersion=\"${version#*.}\"\n                __AlpineVersion=\"$__AlpineMajorVersion.$__AlpineMinorVersion\"\n            fi\n            ;;\n        freebsd13)\n            __CodeName=freebsd\n            __SkipUnmount=1\n            ;;\n        freebsd14)\n            __CodeName=freebsd\n            __FreeBSDBase=\"14.2-RELEASE\"\n            __FreeBSDABI=\"14\"\n            __SkipUnmount=1\n            ;;\n        illumos)\n            __CodeName=illumos\n            __SkipUnmount=1\n            ;;\n        haiku)\n            __CodeName=haiku\n            __SkipUnmount=1\n            ;;\n        --skipunmount)\n            __SkipUnmount=1\n            ;;\n        --skipsigcheck)\n            __SkipSigCheck=1\n            ;;\n        --skipemulation)\n            __SkipEmulation=1\n            ;;\n        --rootfsdir|-rootfsdir)\n            shift\n            __RootfsDir=\"$1\"\n            ;;\n        --use-mirror)\n            __UseMirror=1\n            ;;\n        --use-jobs)\n            shift\n            MAXJOBS=$1\n            ;;\n        *)\n            __UnprocessedBuildArgs=\"$__UnprocessedBuildArgs $1\"\n            ;;\n    esac\n\n    shift\ndone\n\ncase \"$__AlpineVersion\" in\n    3.14) __AlpinePackages+=\" llvm11-libs\" ;;\n    3.15) __AlpinePackages+=\" llvm12-libs\" ;;\n    3.16) __AlpinePackages+=\" llvm13-libs\" ;;\n    3.17) __AlpinePackages+=\" llvm15-libs\" ;;\n    edge) __AlpineLlvmLibsLookup=1 ;;\n    *)\n        if [[ \"$__AlpineArch\" =~ s390x|ppc64le ]]; then\n            __AlpineVersion=3.15 # minimum version that supports lldb-dev\n            __AlpinePackages+=\" llvm12-libs\"\n        elif [[ \"$__AlpineArch\" == \"x86\" ]]; then\n            __AlpineVersion=3.17 # minimum version that supports lldb-dev\n            __AlpinePackages+=\" llvm15-libs\"\n        elif [[ \"$__AlpineArch\" == \"riscv64\" || \"$__AlpineArch\" == \"loongarch64\" ]]; then\n            __AlpineVersion=3.21 # minimum version that supports lldb-dev\n            __AlpinePackages+=\" llvm19-libs\"\n        elif [[ -n \"$__AlpineMajorVersion\" ]]; then\n            # use whichever alpine version is provided and select the latest toolchain libs\n            __AlpineLlvmLibsLookup=1\n        else\n            __AlpineVersion=3.13 # 3.13 to maximize compatibility\n            __AlpinePackages+=\" llvm10-libs\"\n        fi\nesac\n\nif [[ \"$__AlpineVersion\" =~ 3\\.1[345] ]]; then\n    # compiler-rt--static was merged in compiler-rt package in alpine 3.16\n    # for older versions, we need compiler-rt--static, so replace the name\n    __AlpinePackages=\"${__AlpinePackages/compiler-rt/compiler-rt-static}\"\nfi\n\nif [[ \"$__BuildArch\" == \"armel\" ]]; then\n    __LLDB_Package=\"lldb-3.5-dev\"\nfi\n\n__UbuntuPackages+=\" ${__LLDB_Package:-}\"\n\nif [[ -z \"$__UbuntuRepo\" ]]; then\n    __UbuntuRepo=\"http://ports.ubuntu.com/\"\nfi\n\nif [[ -n \"$__LLVM_MajorVersion\" ]]; then\n    __UbuntuPackages+=\" libclang-common-${__LLVM_MajorVersion}${__LLVM_MinorVersion:+.$__LLVM_MinorVersion}-dev\"\nfi\n\nif [[ -z \"$__RootfsDir\" && -n \"$ROOTFS_DIR\" ]]; then\n    __RootfsDir=\"$ROOTFS_DIR\"\nfi\n\nif [[ -z \"$__RootfsDir\" ]]; then\n    __RootfsDir=\"$__CrossDir/../../../.tools/rootfs/$__BuildArch\"\nfi\n\nif [[ -d \"$__RootfsDir\" ]]; then\n    if [[ \"$__SkipUnmount\" == \"0\" ]]; then\n        umount \"$__RootfsDir\"/* || true\n    fi\n    rm -rf \"$__RootfsDir\"\nfi\n\nmkdir -p \"$__RootfsDir\"\n__RootfsDir=\"$( cd \"$__RootfsDir\" && pwd )\"\n\n__hasWget=\nensureDownloadTool()\n{\n    if command -v wget &> /dev/null; then\n        __hasWget=1\n    elif command -v curl &> /dev/null; then\n        __hasWget=0\n    else\n        >&2 echo \"ERROR: either wget or curl is required by this script.\"\n        exit 1\n    fi\n}\n\nif [[ \"$__CodeName\" == \"alpine\" ]]; then\n    __ApkToolsVersion=2.12.11\n    __ApkToolsDir=\"$(mktemp -d)\"\n    __ApkKeysDir=\"$(mktemp -d)\"\n    arch=\"$(uname -m)\"\n\n    ensureDownloadTool\n\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -P \"$__ApkToolsDir\" \"https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v$__ApkToolsVersion/$arch/apk.static\"\n    else\n        curl -SLO --create-dirs --output-dir \"$__ApkToolsDir\" \"https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v$__ApkToolsVersion/$arch/apk.static\"\n    fi\n    if [[ \"$arch\" == \"x86_64\" ]]; then\n      __ApkToolsSHA512SUM=\"53e57b49230da07ef44ee0765b9592580308c407a8d4da7125550957bb72cb59638e04f8892a18b584451c8d841d1c7cb0f0ab680cc323a3015776affaa3be33\"\n    elif [[ \"$arch\" == \"aarch64\" ]]; then\n      __ApkToolsSHA512SUM=\"9e2b37ecb2b56c05dad23d379be84fd494c14bd730b620d0d576bda760588e1f2f59a7fcb2f2080577e0085f23a0ca8eadd993b4e61c2ab29549fdb71969afd0\"\n    else\n      echo \"WARNING: add missing hash for your host architecture. To find the value, use: 'find /tmp -name apk.static -exec sha512sum {} \\;'\"\n    fi\n    echo \"$__ApkToolsSHA512SUM $__ApkToolsDir/apk.static\" | sha512sum -c\n    chmod +x \"$__ApkToolsDir/apk.static\"\n\n    if [[ \"$__AlpineVersion\" == \"edge\" ]]; then\n        version=edge\n    else\n        version=\"v$__AlpineVersion\"\n    fi\n\n    for line in $__AlpineKeys; do\n        id=\"${line%%:*}\"\n        content=\"${line#*:}\"\n\n        echo -e \"-----BEGIN PUBLIC KEY-----\\n$content\\n-----END PUBLIC KEY-----\" > \"$__ApkKeysDir/alpine-devel@lists.alpinelinux.org-$id.rsa.pub\"\n    done\n\n    if [[ \"$__SkipSigCheck\" == \"1\" ]]; then\n        __ApkSignatureArg=\"--allow-untrusted\"\n    else\n        __ApkSignatureArg=\"--keys-dir $__ApkKeysDir\"\n    fi\n\n    if [[ \"$__SkipEmulation\" == \"1\" ]]; then\n        __NoEmulationArg=\"--no-scripts\"\n    fi\n\n    # initialize DB\n    # shellcheck disable=SC2086\n    \"$__ApkToolsDir/apk.static\" \\\n        -X \"http://dl-cdn.alpinelinux.org/alpine/$version/main\" \\\n        -X \"http://dl-cdn.alpinelinux.org/alpine/$version/community\" \\\n        -U $__ApkSignatureArg --root \"$__RootfsDir\" --arch \"$__AlpineArch\" --initdb add\n\n    if [[ \"$__AlpineLlvmLibsLookup\" == 1 ]]; then\n        # shellcheck disable=SC2086\n        __AlpinePackages+=\" $(\"$__ApkToolsDir/apk.static\" \\\n            -X \"http://dl-cdn.alpinelinux.org/alpine/$version/main\" \\\n            -X \"http://dl-cdn.alpinelinux.org/alpine/$version/community\" \\\n            -U $__ApkSignatureArg --root \"$__RootfsDir\" --arch \"$__AlpineArch\" \\\n            search 'llvm*-libs' | grep -E '^llvm' | sort | tail -1 | sed 's/-[^-]*//2g')\"\n    fi\n\n    # install all packages in one go\n    # shellcheck disable=SC2086\n    \"$__ApkToolsDir/apk.static\" \\\n        -X \"http://dl-cdn.alpinelinux.org/alpine/$version/main\" \\\n        -X \"http://dl-cdn.alpinelinux.org/alpine/$version/community\" \\\n        -U $__ApkSignatureArg --root \"$__RootfsDir\" --arch \"$__AlpineArch\" $__NoEmulationArg \\\n        add $__AlpinePackages\n\n    rm -r \"$__ApkToolsDir\"\nelif [[ \"$__CodeName\" == \"freebsd\" ]]; then\n    mkdir -p \"$__RootfsDir\"/usr/local/etc\n    JOBS=${MAXJOBS:=\"$(getconf _NPROCESSORS_ONLN)\"}\n\n    ensureDownloadTool\n\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -O- \"https://download.freebsd.org/ftp/releases/${__FreeBSDArch}/${__FreeBSDMachineArch}/${__FreeBSDBase}/base.txz\" | tar -C \"$__RootfsDir\" -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version\n    else\n        curl -SL \"https://download.freebsd.org/ftp/releases/${__FreeBSDArch}/${__FreeBSDMachineArch}/${__FreeBSDBase}/base.txz\" | tar -C \"$__RootfsDir\" -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version\n    fi\n    echo \"ABI = \\\"FreeBSD:${__FreeBSDABI}:${__FreeBSDMachineArch}\\\"; FINGERPRINTS = \\\"${__RootfsDir}/usr/share/keys\\\"; REPOS_DIR = [\\\"${__RootfsDir}/etc/pkg\\\"]; REPO_AUTOUPDATE = NO; RUN_SCRIPTS = NO;\" > \"${__RootfsDir}\"/usr/local/etc/pkg.conf\n    echo \"FreeBSD: { url: \\\"pkg+http://pkg.FreeBSD.org/\\${ABI}/quarterly\\\", mirror_type: \\\"srv\\\", signature_type: \\\"fingerprints\\\", fingerprints: \\\"/usr/share/keys/pkg\\\", enabled: yes }\" > \"${__RootfsDir}\"/etc/pkg/FreeBSD.conf\n    mkdir -p \"$__RootfsDir\"/tmp\n    # get and build package manager\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -O- \"https://github.com/freebsd/pkg/archive/${__FreeBSDPkg}.tar.gz\" | tar -C \"$__RootfsDir\"/tmp -zxf -\n    else\n        curl -SL \"https://github.com/freebsd/pkg/archive/${__FreeBSDPkg}.tar.gz\" | tar -C \"$__RootfsDir\"/tmp -zxf -\n    fi\n    cd \"$__RootfsDir/tmp/pkg-${__FreeBSDPkg}\"\n    # needed for install to succeed\n    mkdir -p \"$__RootfsDir\"/host/etc\n    ./autogen.sh && ./configure --prefix=\"$__RootfsDir\"/host && make -j \"$JOBS\" && make install\n    rm -rf \"$__RootfsDir/tmp/pkg-${__FreeBSDPkg}\"\n    # install packages we need.\n    INSTALL_AS_USER=$(whoami) \"$__RootfsDir\"/host/sbin/pkg -r \"$__RootfsDir\" -C \"$__RootfsDir\"/usr/local/etc/pkg.conf update\n    # shellcheck disable=SC2086\n    INSTALL_AS_USER=$(whoami) \"$__RootfsDir\"/host/sbin/pkg -r \"$__RootfsDir\" -C \"$__RootfsDir\"/usr/local/etc/pkg.conf install --yes $__FreeBSDPackages\nelif [[ \"$__CodeName\" == \"illumos\" ]]; then\n    mkdir \"$__RootfsDir/tmp\"\n    pushd \"$__RootfsDir/tmp\"\n    JOBS=${MAXJOBS:=\"$(getconf _NPROCESSORS_ONLN)\"}\n\n    ensureDownloadTool\n\n    echo \"Downloading sysroot.\"\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -O- https://github.com/illumos/sysroot/releases/download/20181213-de6af22ae73b-v1/illumos-sysroot-i386-20181213-de6af22ae73b-v1.tar.gz | tar -C \"$__RootfsDir\" -xzf -\n    else\n        curl -SL https://github.com/illumos/sysroot/releases/download/20181213-de6af22ae73b-v1/illumos-sysroot-i386-20181213-de6af22ae73b-v1.tar.gz | tar -C \"$__RootfsDir\" -xzf -\n    fi\n    echo \"Building binutils. Please wait..\"\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -O- https://ftp.gnu.org/gnu/binutils/binutils-2.42.tar.xz | tar -xJf -\n    else\n        curl -SL https://ftp.gnu.org/gnu/binutils/binutils-2.42.tar.xz | tar -xJf -\n    fi\n    mkdir build-binutils && cd build-binutils\n    ../binutils-2.42/configure --prefix=\"$__RootfsDir\" --target=\"${__illumosArch}-sun-solaris2.11\" --program-prefix=\"${__illumosArch}-illumos-\" --with-sysroot=\"$__RootfsDir\"\n    make -j \"$JOBS\" && make install && cd ..\n    echo \"Building gcc. Please wait..\"\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -O- https://ftp.gnu.org/gnu/gcc/gcc-13.3.0/gcc-13.3.0.tar.xz | tar -xJf -\n    else\n        curl -SL https://ftp.gnu.org/gnu/gcc/gcc-13.3.0/gcc-13.3.0.tar.xz | tar -xJf -\n    fi\n    CFLAGS=\"-fPIC\"\n    CXXFLAGS=\"-fPIC\"\n    CXXFLAGS_FOR_TARGET=\"-fPIC\"\n    CFLAGS_FOR_TARGET=\"-fPIC\"\n    export CFLAGS CXXFLAGS CXXFLAGS_FOR_TARGET CFLAGS_FOR_TARGET\n    mkdir build-gcc && cd build-gcc\n    ../gcc-13.3.0/configure --prefix=\"$__RootfsDir\" --target=\"${__illumosArch}-sun-solaris2.11\" --program-prefix=\"${__illumosArch}-illumos-\" --with-sysroot=\"$__RootfsDir\" --with-gnu-as       \\\n        --with-gnu-ld --disable-nls --disable-libgomp --disable-libquadmath --disable-libssp --disable-libvtv --disable-libcilkrts --disable-libada --disable-libsanitizer \\\n        --disable-libquadmath-support --disable-shared --enable-tls\n    make -j \"$JOBS\" && make install && cd ..\n    BaseUrl=https://pkgsrc.smartos.org\n    if [[ \"$__UseMirror\" == 1 ]]; then\n        BaseUrl=https://pkgsrc.smartos.skylime.net\n    fi\n    BaseUrl=\"$BaseUrl/packages/SmartOS/2019Q4/${__illumosArch}/All\"\n    echo \"Downloading manifest\"\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget \"$BaseUrl\"\n    else\n        curl -SLO \"$BaseUrl\"\n    fi\n    echo \"Downloading dependencies.\"\n    read -ra array <<<\"$__IllumosPackages\"\n    for package in \"${array[@]}\"; do\n        echo \"Installing '$package'\"\n        # find last occurrence of package in listing and extract its name\n        package=\"$(sed -En '/.*href=\"('\"$package\"'-[0-9].*).tgz\".*/h;$!d;g;s//\\1/p' All)\"\n        echo \"Resolved name '$package'\"\n        if [[ \"$__hasWget\" == 1 ]]; then\n            wget \"$BaseUrl\"/\"$package\".tgz\n        else\n            curl -SLO \"$BaseUrl\"/\"$package\".tgz\n        fi\n        ar -x \"$package\".tgz\n        tar --skip-old-files -xzf \"$package\".tmp.tg* -C \"$__RootfsDir\" 2>/dev/null\n    done\n    echo \"Cleaning up temporary files.\"\n    popd\n    rm -rf \"$__RootfsDir\"/{tmp,+*}\n    mkdir -p \"$__RootfsDir\"/usr/include/net\n    mkdir -p \"$__RootfsDir\"/usr/include/netpacket\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -P \"$__RootfsDir\"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/bpf.h\n        wget -P \"$__RootfsDir\"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/dlt.h\n        wget -P \"$__RootfsDir\"/usr/include/netpacket https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/inet/sockmods/netpacket/packet.h\n        wget -P \"$__RootfsDir\"/usr/include/sys https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/sys/sdt.h\n    else\n        curl -SLO --create-dirs --output-dir \"$__RootfsDir\"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/bpf.h\n        curl -SLO --create-dirs --output-dir \"$__RootfsDir\"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/dlt.h\n        curl -SLO --create-dirs --output-dir \"$__RootfsDir\"/usr/include/netpacket https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/inet/sockmods/netpacket/packet.h\n        curl -SLO --create-dirs --output-dir \"$__RootfsDir\"/usr/include/sys https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/sys/sdt.h\n    fi\nelif [[ \"$__CodeName\" == \"haiku\" ]]; then\n    JOBS=${MAXJOBS:=\"$(getconf _NPROCESSORS_ONLN)\"}\n\n    echo \"Building Haiku sysroot for $__HaikuArch\"\n    mkdir -p \"$__RootfsDir/tmp\"\n    pushd \"$__RootfsDir/tmp\"\n\n    mkdir \"$__RootfsDir/tmp/download\"\n\n    ensureDownloadTool\n\n    echo \"Downloading Haiku package tools\"\n    git clone https://github.com/haiku/haiku-toolchains-ubuntu --depth 1 \"$__RootfsDir/tmp/script\"\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -O \"$__RootfsDir/tmp/download/hosttools.zip\" \"$(\"$__RootfsDir/tmp/script/fetch.sh\" --hosttools)\"\n    else\n        curl -SLo \"$__RootfsDir/tmp/download/hosttools.zip\" \"$(\"$__RootfsDir/tmp/script/fetch.sh\" --hosttools)\"\n    fi\n\n    unzip -o \"$__RootfsDir/tmp/download/hosttools.zip\" -d \"$__RootfsDir/tmp/bin\"\n\n    HaikuBaseUrl=\"https://eu.hpkg.haiku-os.org/haiku/master/$__HaikuArch/current\"\n    HaikuPortsBaseUrl=\"https://eu.hpkg.haiku-os.org/haikuports/master/$__HaikuArch/current\"\n\n    echo \"Downloading HaikuPorts package repository index...\"\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -P \"$__RootfsDir/tmp/download\" \"$HaikuPortsBaseUrl/repo\"\n    else\n        curl -SLO --create-dirs --output-dir \"$__RootfsDir/tmp/download\" \"$HaikuPortsBaseUrl/repo\"\n    fi\n\n    echo \"Downloading Haiku packages\"\n    read -ra array <<<\"$__HaikuPackages\"\n    for package in \"${array[@]}\"; do\n        echo \"Downloading $package...\"\n        hpkgFilename=\"$(LD_LIBRARY_PATH=\"$__RootfsDir/tmp/bin\" \"$__RootfsDir/tmp/bin/package_repo\" list -f \"$__RootfsDir/tmp/download/repo\" |\n            grep -E \"${package}-\" | sort -V | tail -n 1 | xargs)\"\n        if [ -z \"$hpkgFilename\" ]; then\n            >&2 echo \"ERROR: package $package missing.\"\n            exit 1\n        fi\n        echo \"Resolved filename: $hpkgFilename...\"\n        hpkgDownloadUrl=\"$HaikuPortsBaseUrl/packages/$hpkgFilename\"\n        if [[ \"$__hasWget\" == 1 ]]; then\n            wget -P \"$__RootfsDir/tmp/download\" \"$hpkgDownloadUrl\"\n        else\n            curl -SLO --create-dirs --output-dir \"$__RootfsDir/tmp/download\" \"$hpkgDownloadUrl\"\n        fi\n    done\n    for package in haiku haiku_devel; do\n        echo \"Downloading $package...\"\n        if [[ \"$__hasWget\" == 1 ]]; then\n            hpkgVersion=\"$(wget -qO- \"$HaikuBaseUrl\" | sed -n 's/^.*version: \"\\([^\"]*\\)\".*$/\\1/p')\"\n            wget -P \"$__RootfsDir/tmp/download\" \"$HaikuBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg\"\n        else\n            hpkgVersion=\"$(curl -sSL \"$HaikuBaseUrl\" | sed -n 's/^.*version: \"\\([^\"]*\\)\".*$/\\1/p')\"\n            curl -SLO --create-dirs --output-dir \"$__RootfsDir/tmp/download\" \"$HaikuBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg\"\n        fi\n    done\n\n    # Set up the sysroot\n    echo \"Setting up sysroot and extracting required packages\"\n    mkdir -p \"$__RootfsDir/boot/system\"\n    for file in \"$__RootfsDir/tmp/download/\"*.hpkg; do\n        echo \"Extracting $file...\"\n        LD_LIBRARY_PATH=\"$__RootfsDir/tmp/bin\" \"$__RootfsDir/tmp/bin/package\" extract -C \"$__RootfsDir/boot/system\" \"$file\"\n    done\n\n    # Download buildtools\n    echo \"Downloading Haiku buildtools\"\n    if [[ \"$__hasWget\" == 1 ]]; then\n        wget -O \"$__RootfsDir/tmp/download/buildtools.zip\" \"$(\"$__RootfsDir/tmp/script/fetch.sh\" --buildtools --arch=$__HaikuArch)\"\n    else\n        curl -SLo \"$__RootfsDir/tmp/download/buildtools.zip\" \"$(\"$__RootfsDir/tmp/script/fetch.sh\" --buildtools --arch=$__HaikuArch)\"\n    fi\n    unzip -o \"$__RootfsDir/tmp/download/buildtools.zip\" -d \"$__RootfsDir\"\n\n    # Cleaning up temporary files\n    echo \"Cleaning up temporary files\"\n    popd\n    rm -rf \"$__RootfsDir/tmp\"\nelif [[ -n \"$__CodeName\" ]]; then\n    if [[ \"$__SkipEmulation\" == \"1\" ]]; then\n        if [[ -z \"$AR\" ]]; then\n            if command -v ar &>/dev/null; then\n                AR=\"$(command -v ar)\"\n            elif command -v llvm-ar &>/dev/null; then\n                AR=\"$(command -v llvm-ar)\"\n            else\n                echo \"Unable to find ar or llvm-ar on PATH, add them to PATH or set AR environment variable pointing to the available AR tool\"\n                exit 1\n            fi\n        fi\n\n        # shellcheck disable=SC2086\n        suites=\"$__CodeName $__DebianSuites $(echo $__UbuntuSuites | xargs -n 1 | xargs -I {} echo -n \"$__CodeName-{} \")\"\n\n        PYTHON=${PYTHON_EXECUTABLE:-python3}\n\n        # shellcheck disable=SC2086,SC2046\n        echo running \"$PYTHON\" \"$__CrossDir/install-debs.py\" --arch \"$__UbuntuArch\" --mirror \"$__UbuntuRepo\" --rootfsdir \"$__RootfsDir\" --artool \"$AR\" \\\n            $(echo $suites | xargs -n 1 | xargs -I {} echo -n \"--suite {} \") \\\n            $__UbuntuPackages\n\n        # shellcheck disable=SC2086,SC2046\n        \"$PYTHON\" \"$__CrossDir/install-debs.py\" --arch \"$__UbuntuArch\" --mirror \"$__UbuntuRepo\" --rootfsdir \"$__RootfsDir\" --artool \"$AR\" \\\n            $(echo $suites | xargs -n 1 | xargs -I {} echo -n \"--suite {} \") \\\n            $__UbuntuPackages\n\n        exit 0\n    fi\n\n    __UpdateOptions=\n    if [[ \"$__SkipSigCheck\" == \"0\" ]]; then\n        __Keyring=\"$__Keyring --force-check-gpg\"\n    else\n        __Keyring=\n        __UpdateOptions=\"--allow-unauthenticated --allow-insecure-repositories\"\n    fi\n\n    # shellcheck disable=SC2086\n    echo running debootstrap \"--variant=minbase\" $__Keyring --arch \"$__UbuntuArch\" \"$__CodeName\" \"$__RootfsDir\" \"$__UbuntuRepo\"\n\n    # shellcheck disable=SC2086\n    if ! debootstrap \"--variant=minbase\" $__Keyring --arch \"$__UbuntuArch\" \"$__CodeName\" \"$__RootfsDir\" \"$__UbuntuRepo\"; then\n        echo \"debootstrap failed! dumping debootstrap.log\"\n        cat \"$__RootfsDir/debootstrap/debootstrap.log\"\n        exit 1\n    fi\n\n    rm -rf \"$__RootfsDir\"/etc/apt/*.{sources,list} \"$__RootfsDir\"/etc/apt/sources.list.d\n    mkdir -p \"$__RootfsDir/etc/apt/sources.list.d/\"\n\n    # shellcheck disable=SC2086\n    cat > \"$__RootfsDir/etc/apt/sources.list.d/$__CodeName.sources\" <<EOF\nTypes: deb\nURIs: $__UbuntuRepo\nSuites: $__CodeName $__DebianSuites $(echo $__UbuntuSuites | xargs -n 1 | xargs -I {} echo -n \"$__CodeName-{} \")\nComponents: main universe\nSigned-By: $__KeyringFile\nEOF\n\n    # shellcheck disable=SC2086\n    chroot \"$__RootfsDir\" apt-get update $__UpdateOptions\n    chroot \"$__RootfsDir\" apt-get -f -y install\n    # shellcheck disable=SC2086\n    chroot \"$__RootfsDir\" apt-get -y install $__UbuntuPackages\n    chroot \"$__RootfsDir\" symlinks -cr /usr\n    chroot \"$__RootfsDir\" apt-get clean\n\n    if [[ \"$__SkipUnmount\" == \"0\" ]]; then\n        umount \"$__RootfsDir\"/* || true\n    fi\n\n    if [[ \"$__BuildArch\" == \"armel\" && \"$__CodeName\" == \"jessie\" ]]; then\n        pushd \"$__RootfsDir\"\n        patch -p1 < \"$__CrossDir/$__BuildArch/armel.jessie.patch\"\n        popd\n    fi\nelif [[ \"$__Tizen\" == \"tizen\" ]]; then\n    ROOTFS_DIR=\"$__RootfsDir\" \"$__CrossDir/tizen-build-rootfs.sh\" \"$__BuildArch\"\nelse\n    echo \"Unsupported target platform.\"\n    usage\nfi\n"
  },
  {
    "path": "eng/common/cross/install-debs.py",
    "content": "#!/usr/bin/env python3\n\nimport argparse\nimport asyncio\nimport aiohttp\nimport gzip\nimport os\nimport re\nimport shutil\nimport subprocess\nimport sys\nimport tarfile\nimport tempfile\nimport zstandard\n\nfrom collections import deque\nfrom functools import cmp_to_key\n\nasync def download_file(session, url, dest_path, max_retries=3, retry_delay=2, timeout=60):\n    \"\"\"Asynchronous file download with retries.\"\"\"\n    attempt = 0\n    while attempt < max_retries:\n        try:\n            async with session.get(url, timeout=aiohttp.ClientTimeout(total=timeout)) as response:\n                if response.status == 200:\n                    with open(dest_path, \"wb\") as f:\n                        content = await response.read()\n                        f.write(content)\n                    print(f\"Downloaded {url} at {dest_path}\")\n                    return\n                else:\n                    print(f\"Failed to download {url}, Status Code: {response.status}\")\n                    break\n        except (asyncio.CancelledError, asyncio.TimeoutError, aiohttp.ClientError) as e:\n            print(f\"Error downloading {url}: {type(e).__name__} - {e}. Retrying...\")\n\n        attempt += 1\n        await asyncio.sleep(retry_delay)\n\n    print(f\"Failed to download {url} after {max_retries} attempts.\")\n\nasync def download_deb_files_parallel(mirror, packages, tmp_dir):\n    \"\"\"Download .deb files in parallel.\"\"\"\n    os.makedirs(tmp_dir, exist_ok=True)\n\n    tasks = []\n    timeout = aiohttp.ClientTimeout(total=60)\n    async with aiohttp.ClientSession(timeout=timeout) as session:\n        for pkg, info in packages.items():\n            filename = info.get(\"Filename\")\n            if filename:\n                url = f\"{mirror}/{filename}\"\n                dest_path = os.path.join(tmp_dir, os.path.basename(filename))\n                tasks.append(asyncio.create_task(download_file(session, url, dest_path)))\n\n        await asyncio.gather(*tasks)\n\nasync def download_package_index_parallel(mirror, arch, suites):\n    \"\"\"Download package index files for specified suites and components entirely in memory.\"\"\"\n    tasks = []\n    timeout = aiohttp.ClientTimeout(total=60)\n\n    async with aiohttp.ClientSession(timeout=timeout) as session:\n        for suite in suites:\n            for component in [\"main\", \"universe\"]:\n                url = f\"{mirror}/dists/{suite}/{component}/binary-{arch}/Packages.gz\"\n                tasks.append(fetch_and_decompress(session, url))\n\n        results = await asyncio.gather(*tasks, return_exceptions=True)\n\n    merged_content = \"\"\n    for result in results:\n        if isinstance(result, str):\n            if merged_content:\n                merged_content += \"\\n\\n\"\n            merged_content += result\n\n    return merged_content\n\nasync def fetch_and_decompress(session, url):\n    \"\"\"Fetch and decompress the Packages.gz file.\"\"\"\n    try:\n        async with session.get(url) as response:\n            if response.status == 200:\n                compressed_data = await response.read()\n                decompressed_data = gzip.decompress(compressed_data).decode('utf-8')\n                print(f\"Downloaded index: {url}\")\n                return decompressed_data\n            else:\n                print(f\"Skipped index: {url} (doesn't exist)\")\n                return None\n    except Exception as e:\n        print(f\"Error fetching {url}: {e}\")\n\ndef parse_debian_version(version):\n    \"\"\"Parse a Debian package version into epoch, upstream version, and revision.\"\"\"\n    match = re.match(r'^(?:(\\d+):)?([^-]+)(?:-(.+))?$', version)\n    if not match:\n        raise ValueError(f\"Invalid Debian version format: {version}\")\n    epoch, upstream, revision = match.groups()\n    return int(epoch) if epoch else 0, upstream, revision or \"\"\n\ndef compare_upstream_version(v1, v2):\n    \"\"\"Compare upstream or revision parts using Debian rules.\"\"\"\n    def tokenize(version):\n        tokens = re.split(r'([0-9]+|[A-Za-z]+)', version)\n        return [int(x) if x.isdigit() else x for x in tokens if x]\n\n    tokens1 = tokenize(v1)\n    tokens2 = tokenize(v2)\n\n    for token1, token2 in zip(tokens1, tokens2):\n        if type(token1) == type(token2):\n            if token1 != token2:\n                return (token1 > token2) - (token1 < token2)\n        else:\n            return -1 if isinstance(token1, str) else 1\n\n    return len(tokens1) - len(tokens2)\n\ndef compare_debian_versions(version1, version2):\n    \"\"\"Compare two Debian package versions.\"\"\"\n    epoch1, upstream1, revision1 = parse_debian_version(version1)\n    epoch2, upstream2, revision2 = parse_debian_version(version2)\n\n    if epoch1 != epoch2:\n        return epoch1 - epoch2\n\n    result = compare_upstream_version(upstream1, upstream2)\n    if result != 0:\n        return result\n\n    return compare_upstream_version(revision1, revision2)\n\ndef resolve_dependencies(packages, aliases, desired_packages):\n    \"\"\"Recursively resolves dependencies for the desired packages.\"\"\"\n    resolved = []\n    to_process = deque(desired_packages)\n\n    while to_process:\n        current = to_process.popleft()\n        resolved_package = current if current in packages else aliases.get(current, [None])[0]\n\n        if not resolved_package:\n            print(f\"Error: Package '{current}' was not found in the available packages.\")\n            sys.exit(1)\n\n        if resolved_package not in resolved:\n            resolved.append(resolved_package)\n\n            deps = packages.get(resolved_package, {}).get(\"Depends\", \"\")\n            if deps:\n                deps = [dep.split(' ')[0] for dep in deps.split(', ') if dep]\n                for dep in deps:\n                    if dep not in resolved and dep not in to_process and dep in packages:\n                        to_process.append(dep)\n\n    return resolved\n\ndef parse_package_index(content):\n    \"\"\"Parses the Packages.gz file and returns package information.\"\"\"\n    packages = {}\n    aliases = {}\n    entries = re.split(r'\\n\\n+', content)\n\n    for entry in entries:\n        fields = dict(re.findall(r'^(\\S+): (.+)$', entry, re.MULTILINE))\n        if \"Package\" in fields:\n            package_name = fields[\"Package\"]\n            version = fields.get(\"Version\")\n            filename = fields.get(\"Filename\")\n            depends = fields.get(\"Depends\")\n            provides = fields.get(\"Provides\", None)\n\n            # Only update if package_name is not in packages or if the new version is higher\n            if package_name not in packages or compare_debian_versions(version, packages[package_name][\"Version\"]) > 0:\n                packages[package_name] = {\n                    \"Version\": version,\n                    \"Filename\": filename,\n                    \"Depends\": depends\n                }\n\n                # Update aliases if package provides any alternatives\n                if provides:\n                    provides_list = [x.strip() for x in provides.split(\",\")]\n                    for alias in provides_list:\n                        # Strip version specifiers\n                        alias_name = re.sub(r'\\s*\\(=.*\\)', '', alias)\n                        if alias_name not in aliases:\n                            aliases[alias_name] = []\n                        if package_name not in aliases[alias_name]:\n                            aliases[alias_name].append(package_name)\n\n    return packages, aliases\n\ndef install_packages(mirror, packages_info, aliases, tmp_dir, extract_dir, ar_tool, desired_packages):\n    \"\"\"Downloads .deb files and extracts them.\"\"\"\n    resolved_packages = resolve_dependencies(packages_info, aliases, desired_packages)\n    print(f\"Resolved packages (including dependencies): {resolved_packages}\")\n\n    packages_to_download = {}\n\n    for pkg in resolved_packages:\n        if pkg in packages_info:\n            packages_to_download[pkg] = packages_info[pkg]\n\n        if pkg in aliases:\n            for alias in aliases[pkg]:\n                if alias in packages_info:\n                    packages_to_download[alias] = packages_info[alias]\n\n    asyncio.run(download_deb_files_parallel(mirror, packages_to_download, tmp_dir))\n\n    package_to_deb_file_map = {}\n    for pkg in resolved_packages:\n        pkg_info = packages_info.get(pkg)\n        if pkg_info:\n            deb_filename = pkg_info.get(\"Filename\")\n            if deb_filename:\n                deb_file_path = os.path.join(tmp_dir, os.path.basename(deb_filename))\n                package_to_deb_file_map[pkg] = deb_file_path\n\n    for pkg in reversed(resolved_packages):\n        deb_file = package_to_deb_file_map.get(pkg)\n        if deb_file and os.path.exists(deb_file):\n            extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool)\n\n    print(\"All done!\")\n\ndef extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool):\n    \"\"\"Extract .deb file contents\"\"\"\n\n    os.makedirs(extract_dir, exist_ok=True)\n\n    with tempfile.TemporaryDirectory(dir=tmp_dir) as tmp_subdir:\n        result = subprocess.run(f\"{ar_tool} t {os.path.abspath(deb_file)}\", cwd=tmp_subdir, check=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n        tar_filename = None\n        for line in result.stdout.decode().splitlines():\n            if line.startswith(\"data.tar\"):\n                tar_filename = line.strip()\n                break\n\n        if not tar_filename:\n            raise FileNotFoundError(f\"Could not find 'data.tar.*' in {deb_file}.\")\n\n        tar_file_path = os.path.join(tmp_subdir, tar_filename)\n        print(f\"Extracting {tar_filename} from {deb_file}..\")\n\n        subprocess.run(f\"{ar_tool} p {os.path.abspath(deb_file)} {tar_filename} > {tar_file_path}\", check=True, shell=True)\n\n        file_extension = os.path.splitext(tar_file_path)[1].lower()\n\n        if file_extension == \".xz\":\n            mode = \"r:xz\"\n        elif file_extension == \".gz\":\n            mode = \"r:gz\"\n        elif file_extension == \".zst\":\n            # zstd is not supported by standard library yet\n            decompressed_tar_path = tar_file_path.replace(\".zst\", \"\")\n            with open(tar_file_path, \"rb\") as zst_file, open(decompressed_tar_path, \"wb\") as decompressed_file:\n                dctx = zstandard.ZstdDecompressor()\n                dctx.copy_stream(zst_file, decompressed_file)\n\n            tar_file_path = decompressed_tar_path\n            mode = \"r\"\n        else:\n            raise ValueError(f\"Unsupported compression format: {file_extension}\")\n\n        with tarfile.open(tar_file_path, mode) as tar:\n            tar.extractall(path=extract_dir, filter='fully_trusted')\n\ndef finalize_setup(rootfsdir):\n    lib_dir = os.path.join(rootfsdir, 'lib')\n    usr_lib_dir = os.path.join(rootfsdir, 'usr', 'lib')\n\n    if os.path.exists(lib_dir):\n        if os.path.islink(lib_dir):\n            os.remove(lib_dir)\n        else:\n            os.makedirs(usr_lib_dir, exist_ok=True)\n\n            for item in os.listdir(lib_dir):\n                src = os.path.join(lib_dir, item)\n                dest = os.path.join(usr_lib_dir, item)\n\n                if os.path.isdir(src):\n                    shutil.copytree(src, dest, dirs_exist_ok=True)\n                else:\n                    shutil.copy2(src, dest)\n\n            shutil.rmtree(lib_dir)\n\n    os.symlink(usr_lib_dir, lib_dir)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description=\"Generate rootfs for .NET runtime on Debian-like OS\")\n    parser.add_argument(\"--distro\", required=False, help=\"Distro name (e.g., debian, ubuntu, etc.)\")\n    parser.add_argument(\"--arch\", required=True, help=\"Architecture (e.g., amd64, loong64, etc.)\")\n    parser.add_argument(\"--rootfsdir\", required=True, help=\"Destination directory.\")\n    parser.add_argument('--suite', required=True, action='append', help='Specify one or more repository suites to collect index data.')\n    parser.add_argument(\"--mirror\", required=False, help=\"Mirror (e.g., http://ftp.debian.org/debian-ports etc.)\")\n    parser.add_argument(\"--artool\", required=False, default=\"ar\", help=\"ar tool to extract debs (e.g., ar, llvm-ar etc.)\")\n    parser.add_argument(\"packages\", nargs=\"+\", help=\"List of package names to be installed.\")\n\n    args = parser.parse_args()\n\n    if args.mirror is None:\n        if args.distro == \"ubuntu\":\n            args.mirror = \"http://archive.ubuntu.com/ubuntu\" if args.arch in [\"amd64\", \"i386\"] else \"http://ports.ubuntu.com/ubuntu-ports\"\n        elif args.distro == \"debian\":\n            args.mirror = \"http://ftp.debian.org/debian-ports\"\n        else:\n            raise Exception(\"Unsupported distro\")\n\n    DESIRED_PACKAGES = args.packages + [ # base packages\n        \"dpkg\",\n        \"busybox\",\n        \"libc-bin\",\n        \"base-files\",\n        \"base-passwd\",\n        \"debianutils\"\n    ]\n\n    print(f\"Creating rootfs. rootfsdir: {args.rootfsdir}, distro: {args.distro}, arch: {args.arch}, suites: {args.suite}, mirror: {args.mirror}\")\n\n    package_index_content = asyncio.run(download_package_index_parallel(args.mirror, args.arch, args.suite))\n\n    packages_info, aliases = parse_package_index(package_index_content)\n\n    with tempfile.TemporaryDirectory() as tmp_dir:\n        install_packages(args.mirror, packages_info, aliases, tmp_dir, args.rootfsdir, args.artool, DESIRED_PACKAGES)\n\n    finalize_setup(args.rootfsdir)\n"
  },
  {
    "path": "eng/common/cross/riscv64/tizen/tizen.patch",
    "content": "diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so\n--- a/usr/lib64/libc.so\t2016-12-30 23:00:08.284951863 +0900\n+++ b/usr/lib64/libc.so\t2016-12-30 23:00:32.140951815 +0900\n@@ -2,4 +2,4 @@\n    Use the shared library, but some functions are only in\n    the static library, so try that secondarily.  */\n OUTPUT_FORMAT(elf64-littleriscv)\n-GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib64/ld-linux-riscv64-lp64d.so.1 ) )\n+GROUP ( libc.so.6 libc_nonshared.a  AS_NEEDED ( ld-linux-riscv64-lp64d.so.1 ) )\n"
  },
  {
    "path": "eng/common/cross/tizen-build-rootfs.sh",
    "content": "#!/usr/bin/env bash\nset -e\n\nARCH=$1\nLINK_ARCH=$ARCH\n\ncase \"$ARCH\" in\n    arm)\n        TIZEN_ARCH=\"armv7hl\"\n        ;;\n    armel)\n        TIZEN_ARCH=\"armv7l\"\n        LINK_ARCH=\"arm\"\n        ;;\n    arm64)\n        TIZEN_ARCH=\"aarch64\"\n        ;;\n    x86)\n        TIZEN_ARCH=\"i686\"\n        ;;\n    x64)\n        TIZEN_ARCH=\"x86_64\"\n        LINK_ARCH=\"x86\"\n        ;;\n    riscv64)\n        TIZEN_ARCH=\"riscv64\"\n        LINK_ARCH=\"riscv\"\n        ;;\n    *)\n        echo \"Unsupported architecture for tizen: $ARCH\"\n        exit 1\nesac\n\n__CrossDir=$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\n__TIZEN_CROSSDIR=\"$__CrossDir/${ARCH}/tizen\"\n\nif [[ -z \"$ROOTFS_DIR\" ]]; then\n    echo \"ROOTFS_DIR is not defined.\"\n    exit 1;\nfi\n\nTIZEN_TMP_DIR=$ROOTFS_DIR/tizen_tmp\nmkdir -p $TIZEN_TMP_DIR\n\n# Download files\necho \">>Start downloading files\"\nVERBOSE=1 $__CrossDir/tizen-fetch.sh $TIZEN_TMP_DIR $TIZEN_ARCH\necho \"<<Finish downloading files\"\n\necho \">>Start constructing Tizen rootfs\"\nTIZEN_RPM_FILES=`ls $TIZEN_TMP_DIR/*.rpm`\ncd $ROOTFS_DIR\nfor f in $TIZEN_RPM_FILES; do\n    rpm2cpio $f  | cpio -idm --quiet\ndone\necho \"<<Finish constructing Tizen rootfs\"\n\n# Cleanup tmp\nrm -rf $TIZEN_TMP_DIR\n\n# Configure Tizen rootfs\necho \">>Start configuring Tizen rootfs\"\nln -sfn asm-${LINK_ARCH} ./usr/include/asm\npatch -p1 < $__TIZEN_CROSSDIR/tizen.patch\nif [[ \"$TIZEN_ARCH\" == \"riscv64\" ]]; then\n    echo \"Fixing broken symlinks in $PWD\"\n    rm ./usr/lib64/libresolv.so\n    ln -s ../../lib64/libresolv.so.2 ./usr/lib64/libresolv.so\n    rm ./usr/lib64/libpthread.so\n    ln -s ../../lib64/libpthread.so.0 ./usr/lib64/libpthread.so\n    rm ./usr/lib64/libdl.so\n    ln -s ../../lib64/libdl.so.2 ./usr/lib64/libdl.so\n    rm ./usr/lib64/libutil.so\n    ln -s ../../lib64/libutil.so.1 ./usr/lib64/libutil.so\n    rm ./usr/lib64/libm.so\n    ln -s ../../lib64/libm.so.6 ./usr/lib64/libm.so\n    rm ./usr/lib64/librt.so\n    ln -s ../../lib64/librt.so.1 ./usr/lib64/librt.so\n    rm ./lib/ld-linux-riscv64-lp64d.so.1\n    ln -s ../lib64/ld-linux-riscv64-lp64d.so.1 ./lib/ld-linux-riscv64-lp64d.so.1\nfi\necho \"<<Finish configuring Tizen rootfs\"\n"
  },
  {
    "path": "eng/common/cross/tizen-fetch.sh",
    "content": "#!/usr/bin/env bash\nset -e\n\nif [[ -z \"${VERBOSE// }\" ]] || [ \"$VERBOSE\" -ne \"$VERBOSE\" ] 2>/dev/null; then\n    VERBOSE=0\nfi\n\nLog()\n{\n    if [ $VERBOSE -ge 1 ]; then\n        echo ${@:2}\n    fi\n}\n\nInform()\n{\n    Log 1 -e \"\\x1B[0;34m$@\\x1B[m\"\n}\n\nDebug()\n{\n    Log 2 -e \"\\x1B[0;32m$@\\x1B[m\"\n}\n\nError()\n{\n    >&2 Log 0 -e \"\\x1B[0;31m$@\\x1B[m\"\n}\n\nFetch()\n{\n    URL=$1\n    FILE=$2\n    PROGRESS=$3\n    if [ $VERBOSE -ge 1 ] && [ $PROGRESS ]; then\n        CURL_OPT=\"--progress-bar\"\n    else\n        CURL_OPT=\"--silent\"\n    fi\n    curl $CURL_OPT $URL > $FILE\n}\n\nhash curl 2> /dev/null || { Error \"Require 'curl' Aborting.\"; exit 1; }\nhash xmllint 2> /dev/null || { Error \"Require 'xmllint' Aborting.\"; exit 1; }\nhash sha256sum 2> /dev/null || { Error \"Require 'sha256sum' Aborting.\"; exit 1; }\n\nTMPDIR=$1\nif [ ! -d $TMPDIR ]; then\n    TMPDIR=./tizen_tmp\n    Debug \"Create temporary directory : $TMPDIR\"\n    mkdir -p $TMPDIR\nfi\n\nTIZEN_ARCH=$2\n\nTIZEN_URL=http://download.tizen.org/snapshots/TIZEN/Tizen\nBUILD_XML=build.xml\nREPOMD_XML=repomd.xml\nPRIMARY_XML=primary.xml\nTARGET_URL=\"http://__not_initialized\"\n\nXpath_get()\n{\n    XPATH_RESULT=''\n    XPATH=$1\n    XML_FILE=$2\n    RESULT=$(xmllint --xpath $XPATH $XML_FILE)\n    if [[ -z ${RESULT// } ]]; then\n        Error \"Can not find target from $XML_FILE\"\n        Debug \"Xpath = $XPATH\"\n        exit 1\n    fi\n    XPATH_RESULT=$RESULT\n}\n\nfetch_tizen_pkgs_init()\n{\n    TARGET=$1\n    PROFILE=$2\n    Debug \"Initialize TARGET=$TARGET, PROFILE=$PROFILE\"\n\n    TMP_PKG_DIR=$TMPDIR/tizen_${PROFILE}_pkgs\n    if [ -d $TMP_PKG_DIR ]; then rm -rf $TMP_PKG_DIR; fi\n    mkdir -p $TMP_PKG_DIR\n\n    PKG_URL=$TIZEN_URL/$PROFILE/latest\n\n    BUILD_XML_URL=$PKG_URL/$BUILD_XML\n    TMP_BUILD=$TMP_PKG_DIR/$BUILD_XML\n    TMP_REPOMD=$TMP_PKG_DIR/$REPOMD_XML\n    TMP_PRIMARY=$TMP_PKG_DIR/$PRIMARY_XML\n    TMP_PRIMARYGZ=${TMP_PRIMARY}.gz\n\n    Fetch $BUILD_XML_URL $TMP_BUILD\n\n    Debug \"fetch $BUILD_XML_URL to $TMP_BUILD\"\n\n    TARGET_XPATH=\"//build/buildtargets/buildtarget[@name=\\\"$TARGET\\\"]/repo[@type=\\\"binary\\\"]/text()\"\n    Xpath_get $TARGET_XPATH $TMP_BUILD\n    TARGET_PATH=$XPATH_RESULT\n    TARGET_URL=$PKG_URL/$TARGET_PATH\n\n    REPOMD_URL=$TARGET_URL/repodata/repomd.xml\n    PRIMARY_XPATH='string(//*[local-name()=\"data\"][@type=\"primary\"]/*[local-name()=\"location\"]/@href)'\n\n    Fetch $REPOMD_URL $TMP_REPOMD\n\n    Debug \"fetch $REPOMD_URL to $TMP_REPOMD\"\n\n    Xpath_get $PRIMARY_XPATH $TMP_REPOMD\n    PRIMARY_XML_PATH=$XPATH_RESULT\n    PRIMARY_URL=$TARGET_URL/$PRIMARY_XML_PATH\n\n    Fetch $PRIMARY_URL $TMP_PRIMARYGZ\n\n    Debug \"fetch $PRIMARY_URL to $TMP_PRIMARYGZ\"\n\n    gunzip $TMP_PRIMARYGZ\n\n    Debug \"unzip $TMP_PRIMARYGZ to $TMP_PRIMARY\"\n}\n\nfetch_tizen_pkgs()\n{\n    ARCH=$1\n    PACKAGE_XPATH_TPL='string(//*[local-name()=\"metadata\"]/*[local-name()=\"package\"][*[local-name()=\"name\"][text()=\"_PKG_\"]][*[local-name()=\"arch\"][text()=\"_ARCH_\"]]/*[local-name()=\"location\"]/@href)'\n\n    PACKAGE_CHECKSUM_XPATH_TPL='string(//*[local-name()=\"metadata\"]/*[local-name()=\"package\"][*[local-name()=\"name\"][text()=\"_PKG_\"]][*[local-name()=\"arch\"][text()=\"_ARCH_\"]]/*[local-name()=\"checksum\"]/text())'\n\n    for pkg in ${@:2}\n    do\n        Inform \"Fetching... $pkg\"\n        XPATH=${PACKAGE_XPATH_TPL/_PKG_/$pkg}\n        XPATH=${XPATH/_ARCH_/$ARCH}\n        Xpath_get $XPATH $TMP_PRIMARY\n        PKG_PATH=$XPATH_RESULT\n\n        XPATH=${PACKAGE_CHECKSUM_XPATH_TPL/_PKG_/$pkg}\n        XPATH=${XPATH/_ARCH_/$ARCH}\n        Xpath_get $XPATH $TMP_PRIMARY\n        CHECKSUM=$XPATH_RESULT\n\n        PKG_URL=$TARGET_URL/$PKG_PATH\n        PKG_FILE=$(basename $PKG_PATH)\n        PKG_PATH=$TMPDIR/$PKG_FILE\n\n        Debug \"Download $PKG_URL to $PKG_PATH\"\n        Fetch $PKG_URL $PKG_PATH true\n\n        echo \"$CHECKSUM $PKG_PATH\" | sha256sum -c - > /dev/null\n        if [ $? -ne 0 ]; then\n            Error \"Fail to fetch $PKG_URL to $PKG_PATH\"\n            Debug \"Checksum = $CHECKSUM\"\n            exit 1\n        fi\n    done\n}\n\nif [ \"$TIZEN_ARCH\" == \"riscv64\" ]; then\n    BASE=\"Tizen-Base-RISCV\"\n    UNIFIED=\"Tizen-Unified-RISCV\"\nelse\n    BASE=\"Tizen-Base\"\n    UNIFIED=\"Tizen-Unified\"\nfi\n\nInform \"Initialize ${TIZEN_ARCH} base\"\nfetch_tizen_pkgs_init standard $BASE\nInform \"fetch common packages\"\nfetch_tizen_pkgs ${TIZEN_ARCH} gcc gcc-devel-static glibc glibc-devel libicu libicu-devel libatomic linux-glibc-devel keyutils keyutils-devel libkeyutils\nInform \"fetch coreclr packages\"\nfetch_tizen_pkgs ${TIZEN_ARCH} libgcc libstdc++ libstdc++-devel libunwind libunwind-devel lttng-ust-devel lttng-ust userspace-rcu-devel userspace-rcu\nif [ \"$TIZEN_ARCH\" != \"riscv64\" ]; then\n    fetch_tizen_pkgs ${TIZEN_ARCH} lldb lldb-devel\nfi\nInform \"fetch corefx packages\"\nfetch_tizen_pkgs ${TIZEN_ARCH} libcom_err libcom_err-devel zlib zlib-devel libopenssl11 libopenssl1.1-devel krb5 krb5-devel\n\nInform \"Initialize standard unified\"\nfetch_tizen_pkgs_init standard $UNIFIED\nInform \"fetch corefx packages\"\nfetch_tizen_pkgs ${TIZEN_ARCH} gssdp gssdp-devel tizen-release\n\n"
  },
  {
    "path": "eng/common/cross/toolchain.cmake",
    "content": "set(CROSS_ROOTFS $ENV{ROOTFS_DIR})\n\n# reset platform variables (e.g. cmake 3.25 sets LINUX=1)\nunset(LINUX)\nunset(FREEBSD)\nunset(ILLUMOS)\nunset(ANDROID)\nunset(TIZEN)\nunset(HAIKU)\n\nset(TARGET_ARCH_NAME $ENV{TARGET_BUILD_ARCH})\nif(EXISTS ${CROSS_ROOTFS}/bin/freebsd-version)\n  set(CMAKE_SYSTEM_NAME FreeBSD)\n  set(FREEBSD 1)\nelseif(EXISTS ${CROSS_ROOTFS}/usr/platform/i86pc)\n  set(CMAKE_SYSTEM_NAME SunOS)\n  set(ILLUMOS 1)\nelseif(EXISTS ${CROSS_ROOTFS}/boot/system/develop/headers/config/HaikuConfig.h)\n  set(CMAKE_SYSTEM_NAME Haiku)\n  set(HAIKU 1)\nelse()\n  set(CMAKE_SYSTEM_NAME Linux)\n  set(LINUX 1)\nendif()\nset(CMAKE_SYSTEM_VERSION 1)\n\nif(EXISTS ${CROSS_ROOTFS}/etc/tizen-release)\n  set(TIZEN 1)\nelseif(EXISTS ${CROSS_ROOTFS}/android_platform)\n  set(ANDROID 1)\nendif()\n\nif(TARGET_ARCH_NAME STREQUAL \"arm\")\n  set(CMAKE_SYSTEM_PROCESSOR armv7l)\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv7-alpine-linux-musleabihf)\n    set(TOOLCHAIN \"armv7-alpine-linux-musleabihf\")\n  elseif(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf)\n    set(TOOLCHAIN \"armv6-alpine-linux-musleabihf\")\n  else()\n    set(TOOLCHAIN \"arm-linux-gnueabihf\")\n  endif()\n  if(TIZEN)\n    set(TIZEN_TOOLCHAIN \"armv7hl-tizen-linux-gnueabihf\")\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"arm64\")\n  set(CMAKE_SYSTEM_PROCESSOR aarch64)\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/aarch64-alpine-linux-musl)\n    set(TOOLCHAIN \"aarch64-alpine-linux-musl\")\n  elseif(LINUX)\n    set(TOOLCHAIN \"aarch64-linux-gnu\")\n    if(TIZEN)\n      set(TIZEN_TOOLCHAIN \"aarch64-tizen-linux-gnu\")\n    endif()\n  elseif(FREEBSD)\n    set(triple \"aarch64-unknown-freebsd12\")\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"armel\")\n  set(CMAKE_SYSTEM_PROCESSOR armv7l)\n  set(TOOLCHAIN \"arm-linux-gnueabi\")\n  if(TIZEN)\n    set(TIZEN_TOOLCHAIN \"armv7l-tizen-linux-gnueabi\")\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"armv6\")\n  set(CMAKE_SYSTEM_PROCESSOR armv6l)\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf)\n    set(TOOLCHAIN \"armv6-alpine-linux-musleabihf\")\n  else()\n    set(TOOLCHAIN \"arm-linux-gnueabihf\")\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"loongarch64\")\n  set(CMAKE_SYSTEM_PROCESSOR \"loongarch64\")\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/loongarch64-alpine-linux-musl)\n    set(TOOLCHAIN \"loongarch64-alpine-linux-musl\")\n  else()\n    set(TOOLCHAIN \"loongarch64-linux-gnu\")\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"ppc64le\")\n  set(CMAKE_SYSTEM_PROCESSOR ppc64le)\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/powerpc64le-alpine-linux-musl)\n    set(TOOLCHAIN \"powerpc64le-alpine-linux-musl\")\n  else()\n    set(TOOLCHAIN \"powerpc64le-linux-gnu\")\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"riscv64\")\n  set(CMAKE_SYSTEM_PROCESSOR riscv64)\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/riscv64-alpine-linux-musl)\n    set(TOOLCHAIN \"riscv64-alpine-linux-musl\")\n  else()\n    set(TOOLCHAIN \"riscv64-linux-gnu\")\n    if(TIZEN)\n      set(TIZEN_TOOLCHAIN \"riscv64-tizen-linux-gnu\")\n    endif()\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"s390x\")\n  set(CMAKE_SYSTEM_PROCESSOR s390x)\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/s390x-alpine-linux-musl)\n    set(TOOLCHAIN \"s390x-alpine-linux-musl\")\n  else()\n    set(TOOLCHAIN \"s390x-linux-gnu\")\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"x64\")\n  set(CMAKE_SYSTEM_PROCESSOR x86_64)\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/x86_64-alpine-linux-musl)\n    set(TOOLCHAIN \"x86_64-alpine-linux-musl\")\n  elseif(LINUX)\n    set(TOOLCHAIN \"x86_64-linux-gnu\")\n    if(TIZEN)\n      set(TIZEN_TOOLCHAIN \"x86_64-tizen-linux-gnu\")\n    endif()\n  elseif(FREEBSD)\n    set(triple \"x86_64-unknown-freebsd12\")\n  elseif(ILLUMOS)\n    set(TOOLCHAIN \"x86_64-illumos\")\n  elseif(HAIKU)\n    set(TOOLCHAIN \"x86_64-unknown-haiku\")\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"x86\")\n  set(CMAKE_SYSTEM_PROCESSOR i686)\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/i586-alpine-linux-musl)\n    set(TOOLCHAIN \"i586-alpine-linux-musl\")\n  else()\n    set(TOOLCHAIN \"i686-linux-gnu\")\n  endif()\n  if(TIZEN)\n    set(TIZEN_TOOLCHAIN \"i586-tizen-linux-gnu\")\n  endif()\nelse()\n  message(FATAL_ERROR \"Arch is ${TARGET_ARCH_NAME}. Only arm, arm64, armel, armv6, loongarch64, ppc64le, riscv64, s390x, x64 and x86 are supported!\")\nendif()\n\nif(DEFINED ENV{TOOLCHAIN})\n  set(TOOLCHAIN $ENV{TOOLCHAIN})\nendif()\n\n# Specify include paths\nif(TIZEN)\n  function(find_toolchain_dir prefix)\n    # Dynamically find the version subdirectory\n    file(GLOB DIRECTORIES \"${prefix}/*\")\n    list(GET DIRECTORIES 0 FIRST_MATCH)\n    get_filename_component(TOOLCHAIN_VERSION ${FIRST_MATCH} NAME)\n\n    set(TIZEN_TOOLCHAIN_PATH \"${prefix}/${TOOLCHAIN_VERSION}\" PARENT_SCOPE)\n  endfunction()\n\n  if(TARGET_ARCH_NAME MATCHES \"^(arm|armel|x86)$\")\n    find_toolchain_dir(\"${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}\")\n  else()\n    find_toolchain_dir(\"${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}\")\n  endif()\n\n  message(STATUS \"TIZEN_TOOLCHAIN_PATH set to: ${TIZEN_TOOLCHAIN_PATH}\")\n\n  include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++)\n  include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++/${TIZEN_TOOLCHAIN})\nendif()\n\nfunction(locate_toolchain_exec exec var)\n    set(TOOLSET_PREFIX ${TOOLCHAIN}-)\n    string(TOUPPER ${exec} EXEC_UPPERCASE)\n    if(NOT \"$ENV{CLR_${EXEC_UPPERCASE}}\" STREQUAL \"\")\n        set(${var} \"$ENV{CLR_${EXEC_UPPERCASE}}\" PARENT_SCOPE)\n        return()\n    endif()\n\n    find_program(EXEC_LOCATION_${exec}\n        NAMES\n        \"${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}\"\n        \"${TOOLSET_PREFIX}${exec}\")\n\n    if (EXEC_LOCATION_${exec} STREQUAL \"EXEC_LOCATION_${exec}-NOTFOUND\")\n        message(FATAL_ERROR \"Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.\")\n    endif()\n    set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE)\nendfunction()\n\nif(ANDROID)\n    if(TARGET_ARCH_NAME STREQUAL \"arm\")\n        set(ANDROID_ABI armeabi-v7a)\n    elseif(TARGET_ARCH_NAME STREQUAL \"arm64\")\n        set(ANDROID_ABI arm64-v8a)\n    endif()\n\n    # extract platform number required by the NDK's toolchain\n    file(READ \"${CROSS_ROOTFS}/android_platform\" RID_FILE_CONTENTS)\n    string(REPLACE \"RID=\" \"\" ANDROID_RID \"${RID_FILE_CONTENTS}\")\n    string(REGEX REPLACE \".*\\\\.([0-9]+)-.*\" \"\\\\1\" ANDROID_PLATFORM \"${ANDROID_RID}\")\n\n    set(ANDROID_TOOLCHAIN clang)\n    set(FEATURE_EVENT_TRACE 0) # disable event trace as there is no lttng-ust package in termux repository\n    set(CMAKE_SYSTEM_LIBRARY_PATH \"${CROSS_ROOTFS}/usr/lib\")\n    set(CMAKE_SYSTEM_INCLUDE_PATH \"${CROSS_ROOTFS}/usr/include\")\n\n    # include official NDK toolchain script\n    include(${CROSS_ROOTFS}/../build/cmake/android.toolchain.cmake)\nelseif(FREEBSD)\n    # we cross-compile by instructing clang\n    set(CMAKE_C_COMPILER_TARGET ${triple})\n    set(CMAKE_CXX_COMPILER_TARGET ${triple})\n    set(CMAKE_ASM_COMPILER_TARGET ${triple})\n    set(CMAKE_SYSROOT \"${CROSS_ROOTFS}\")\n    set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld\")\n    set(CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=lld\")\n    set(CMAKE_MODULE_LINKER_FLAGS \"${CMAKE_MODULE_LINKER_FLAGS} -fuse-ld=lld\")\nelseif(ILLUMOS)\n    set(CMAKE_SYSROOT \"${CROSS_ROOTFS}\")\n    set(CMAKE_SYSTEM_PREFIX_PATH \"${CROSS_ROOTFS}\")\n    set(CMAKE_C_STANDARD_LIBRARIES \"${CMAKE_C_STANDARD_LIBRARIES} -lssp\")\n    set(CMAKE_CXX_STANDARD_LIBRARIES \"${CMAKE_CXX_STANDARD_LIBRARIES} -lssp\")\n\n    include_directories(SYSTEM ${CROSS_ROOTFS}/include)\n\n    locate_toolchain_exec(gcc CMAKE_C_COMPILER)\n    locate_toolchain_exec(g++ CMAKE_CXX_COMPILER)\nelseif(HAIKU)\n    set(CMAKE_SYSROOT \"${CROSS_ROOTFS}\")\n    set(CMAKE_PROGRAM_PATH \"${CMAKE_PROGRAM_PATH};${CROSS_ROOTFS}/cross-tools-x86_64/bin\")\n    set(CMAKE_SYSTEM_PREFIX_PATH \"${CROSS_ROOTFS}\")\n    set(CMAKE_C_STANDARD_LIBRARIES \"${CMAKE_C_STANDARD_LIBRARIES} -lssp\")\n    set(CMAKE_CXX_STANDARD_LIBRARIES \"${CMAKE_CXX_STANDARD_LIBRARIES} -lssp\")\n\n    locate_toolchain_exec(gcc CMAKE_C_COMPILER)\n    locate_toolchain_exec(g++ CMAKE_CXX_COMPILER)\n\n    # let CMake set up the correct search paths\n    include(Platform/Haiku)\nelse()\n    set(CMAKE_SYSROOT \"${CROSS_ROOTFS}\")\n\n    set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN \"${CROSS_ROOTFS}/usr\")\n    set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN \"${CROSS_ROOTFS}/usr\")\n    set(CMAKE_ASM_COMPILER_EXTERNAL_TOOLCHAIN \"${CROSS_ROOTFS}/usr\")\nendif()\n\n# Specify link flags\n\nfunction(add_toolchain_linker_flag Flag)\n  set(Config \"${ARGV1}\")\n  set(CONFIG_SUFFIX \"\")\n  if (NOT Config STREQUAL \"\")\n    set(CONFIG_SUFFIX \"_${Config}\")\n  endif()\n  set(\"CMAKE_EXE_LINKER_FLAGS${CONFIG_SUFFIX}_INIT\" \"${CMAKE_EXE_LINKER_FLAGS${CONFIG_SUFFIX}_INIT} ${Flag}\" PARENT_SCOPE)\n  set(\"CMAKE_SHARED_LINKER_FLAGS${CONFIG_SUFFIX}_INIT\" \"${CMAKE_SHARED_LINKER_FLAGS${CONFIG_SUFFIX}_INIT} ${Flag}\" PARENT_SCOPE)\nendfunction()\n\nif(LINUX)\n  add_toolchain_linker_flag(\"-Wl,--rpath-link=${CROSS_ROOTFS}/lib/${TOOLCHAIN}\")\n  add_toolchain_linker_flag(\"-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib/${TOOLCHAIN}\")\nendif()\n\nif(TARGET_ARCH_NAME MATCHES \"^(arm|armel)$\")\n  if(TIZEN)\n    add_toolchain_linker_flag(\"-B${TIZEN_TOOLCHAIN_PATH}\")\n    add_toolchain_linker_flag(\"-L${CROSS_ROOTFS}/lib\")\n    add_toolchain_linker_flag(\"-L${CROSS_ROOTFS}/usr/lib\")\n    add_toolchain_linker_flag(\"-L${TIZEN_TOOLCHAIN_PATH}\")\n  endif()\nelseif(TARGET_ARCH_NAME MATCHES \"^(arm64|x64|riscv64)$\")\n  if(TIZEN)\n    add_toolchain_linker_flag(\"-B${TIZEN_TOOLCHAIN_PATH}\")\n    add_toolchain_linker_flag(\"-L${CROSS_ROOTFS}/lib64\")\n    add_toolchain_linker_flag(\"-L${CROSS_ROOTFS}/usr/lib64\")\n    add_toolchain_linker_flag(\"-L${TIZEN_TOOLCHAIN_PATH}\")\n\n    add_toolchain_linker_flag(\"-Wl,--rpath-link=${CROSS_ROOTFS}/lib64\")\n    add_toolchain_linker_flag(\"-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64\")\n    add_toolchain_linker_flag(\"-Wl,--rpath-link=${TIZEN_TOOLCHAIN_PATH}\")\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"s390x\")\n  add_toolchain_linker_flag(\"--target=${TOOLCHAIN}\")\nelseif(TARGET_ARCH_NAME STREQUAL \"x86\")\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/i586-alpine-linux-musl)\n    add_toolchain_linker_flag(\"--target=${TOOLCHAIN}\")\n    add_toolchain_linker_flag(\"-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib/gcc/${TOOLCHAIN}\")\n  endif()\n  add_toolchain_linker_flag(-m32)\n  if(TIZEN)\n    add_toolchain_linker_flag(\"-B${TIZEN_TOOLCHAIN_PATH}\")\n    add_toolchain_linker_flag(\"-L${CROSS_ROOTFS}/lib\")\n    add_toolchain_linker_flag(\"-L${CROSS_ROOTFS}/usr/lib\")\n    add_toolchain_linker_flag(\"-L${TIZEN_TOOLCHAIN_PATH}\")\n  endif()\nelseif(ILLUMOS)\n  add_toolchain_linker_flag(\"-L${CROSS_ROOTFS}/lib/amd64\")\n  add_toolchain_linker_flag(\"-L${CROSS_ROOTFS}/usr/amd64/lib\")\nelseif(HAIKU)\n  add_toolchain_linker_flag(\"-lnetwork\")\n  add_toolchain_linker_flag(\"-lroot\")\nendif()\n\n# Specify compile options\n\nif((TARGET_ARCH_NAME MATCHES \"^(arm|arm64|armel|armv6|loongarch64|ppc64le|riscv64|s390x|x64|x86)$\" AND NOT ANDROID AND NOT FREEBSD) OR ILLUMOS OR HAIKU)\n  set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN})\n  set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN})\n  set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN})\nendif()\n\nif(TARGET_ARCH_NAME MATCHES \"^(arm|armel)$\")\n  add_compile_options(-mthumb)\n  if (NOT DEFINED CLR_ARM_FPU_TYPE)\n    set (CLR_ARM_FPU_TYPE vfpv3)\n  endif (NOT DEFINED CLR_ARM_FPU_TYPE)\n\n  add_compile_options (-mfpu=${CLR_ARM_FPU_TYPE})\n  if (NOT DEFINED CLR_ARM_FPU_CAPABILITY)\n    set (CLR_ARM_FPU_CAPABILITY 0x7)\n  endif (NOT DEFINED CLR_ARM_FPU_CAPABILITY)\n\n  add_definitions (-DCLR_ARM_FPU_CAPABILITY=${CLR_ARM_FPU_CAPABILITY})\n\n  # persist variables across multiple try_compile passes\n  list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CLR_ARM_FPU_TYPE CLR_ARM_FPU_CAPABILITY)\n\n  if(TARGET_ARCH_NAME STREQUAL \"armel\")\n    add_compile_options(-mfloat-abi=softfp)\n  endif()\nelseif(TARGET_ARCH_NAME STREQUAL \"s390x\")\n  add_compile_options(\"--target=${TOOLCHAIN}\")\nelseif(TARGET_ARCH_NAME STREQUAL \"x86\")\n  if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/i586-alpine-linux-musl)\n    add_compile_options(--target=${TOOLCHAIN})\n  endif()\n  add_compile_options(-m32)\n  add_compile_options(-Wno-error=unused-command-line-argument)\nendif()\n\nif(TIZEN)\n  if(TARGET_ARCH_NAME MATCHES \"^(arm|armel|arm64|x86)$\")\n    add_compile_options(-Wno-deprecated-declarations) # compile-time option\n    add_compile_options(-D__extern_always_inline=inline) # compile-time option\n  endif()\nendif()\n\n# Set LLDB include and library paths for builds that need lldb.\nif(TARGET_ARCH_NAME MATCHES \"^(arm|armel|x86)$\")\n  if(TARGET_ARCH_NAME STREQUAL \"x86\")\n    set(LLVM_CROSS_DIR \"$ENV{LLVM_CROSS_HOME}\")\n  else() # arm/armel case\n    set(LLVM_CROSS_DIR \"$ENV{LLVM_ARM_HOME}\")\n  endif()\n  if(LLVM_CROSS_DIR)\n    set(WITH_LLDB_LIBS \"${LLVM_CROSS_DIR}/lib/\" CACHE STRING \"\")\n    set(WITH_LLDB_INCLUDES \"${LLVM_CROSS_DIR}/include\" CACHE STRING \"\")\n    set(LLDB_H \"${WITH_LLDB_INCLUDES}\" CACHE STRING \"\")\n    set(LLDB \"${LLVM_CROSS_DIR}/lib/liblldb.so\" CACHE STRING \"\")\n  else()\n    if(TARGET_ARCH_NAME STREQUAL \"x86\")\n      set(WITH_LLDB_LIBS \"${CROSS_ROOTFS}/usr/lib/i386-linux-gnu\" CACHE STRING \"\")\n      set(CHECK_LLVM_DIR \"${CROSS_ROOTFS}/usr/lib/llvm-3.8/include\")\n      if(EXISTS \"${CHECK_LLVM_DIR}\" AND IS_DIRECTORY \"${CHECK_LLVM_DIR}\")\n        set(WITH_LLDB_INCLUDES \"${CHECK_LLVM_DIR}\")\n      else()\n        set(WITH_LLDB_INCLUDES \"${CROSS_ROOTFS}/usr/lib/llvm-3.6/include\")\n      endif()\n    else() # arm/armel case\n      set(WITH_LLDB_LIBS \"${CROSS_ROOTFS}/usr/lib/${TOOLCHAIN}\" CACHE STRING \"\")\n      set(WITH_LLDB_INCLUDES \"${CROSS_ROOTFS}/usr/lib/llvm-3.6/include\" CACHE STRING \"\")\n    endif()\n  endif()\nendif()\n\n# Set C++ standard library options if specified\nset(CLR_CMAKE_CXX_STANDARD_LIBRARY \"\" CACHE STRING \"Standard library flavor to link against. Only supported with the Clang compiler.\")\nif (CLR_CMAKE_CXX_STANDARD_LIBRARY)\n  add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:--stdlib=${CLR_CMAKE_CXX_STANDARD_LIBRARY}>)\n  add_link_options($<$<LINK_LANG_AND_ID:CXX,Clang>:--stdlib=${CLR_CMAKE_CXX_STANDARD_LIBRARY}>)\nendif()\n\noption(CLR_CMAKE_CXX_STANDARD_LIBRARY_STATIC \"Statically link against the C++ standard library\" OFF)\nif(CLR_CMAKE_CXX_STANDARD_LIBRARY_STATIC)\n  add_link_options($<$<LINK_LANGUAGE:CXX>:-static-libstdc++>)\nendif()\n\nset(CLR_CMAKE_CXX_ABI_LIBRARY \"\" CACHE STRING \"C++ ABI implementation library to link against. Only supported with the Clang compiler.\")\nif (CLR_CMAKE_CXX_ABI_LIBRARY)\n  # The user may specify the ABI library with the 'lib' prefix, like 'libstdc++'. Strip the prefix here so the linker finds the right library.\n  string(REGEX REPLACE \"^lib(.+)\" \"\\\\1\" CLR_CMAKE_CXX_ABI_LIBRARY ${CLR_CMAKE_CXX_ABI_LIBRARY})\n  # We need to specify this as a linker-backend option as Clang will filter this option out when linking to libc++.\n  add_link_options(\"LINKER:-l${CLR_CMAKE_CXX_ABI_LIBRARY}\")\nendif()\n\nset(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\nset(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)\nset(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)\nset(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)\n"
  },
  {
    "path": "eng/common/cross/x86/tizen/tizen.patch",
    "content": "diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so\n--- a/usr/lib/libc.so\t2016-12-30 23:00:08.284951863 +0900\n+++ b/usr/lib/libc.so\t2016-12-30 23:00:32.140951815 +0900\n@@ -2,4 +2,4 @@\n    Use the shared library, but some functions are only in\n    the static library, so try that secondarily.  */\n OUTPUT_FORMAT(elf32-i386)\n-GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux.so.2 ) )\n+GROUP ( libc.so.6 libc_nonshared.a  AS_NEEDED ( ld-linux.so.2 ) )\n"
  },
  {
    "path": "eng/common/darc-init.ps1",
    "content": "param (\n    $darcVersion = $null,\n    $versionEndpoint = 'https://maestro.dot.net/api/assets/darc-version?api-version=2020-02-20',\n    $verbosity = 'minimal',\n    $toolpath = $null\n)\n\n. $PSScriptRoot\\tools.ps1\n\nfunction InstallDarcCli ($darcVersion, $toolpath) {\n  $darcCliPackageName = 'microsoft.dotnet.darc'\n\n  $dotnetRoot = InitializeDotNetCli -install:$true\n  $dotnet = \"$dotnetRoot\\dotnet.exe\"\n  $toolList = & \"$dotnet\" tool list -g\n\n  if ($toolList -like \"*$darcCliPackageName*\") {\n    & \"$dotnet\" tool uninstall $darcCliPackageName -g\n  }\n\n  # If the user didn't explicitly specify the darc version,\n  # query the Maestro API for the correct version of darc to install.\n  if (-not $darcVersion) {\n    $darcVersion = $(Invoke-WebRequest -Uri $versionEndpoint -UseBasicParsing).Content\n  }\n\n  $arcadeServicesSource = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'\n\n  Write-Host \"Installing Darc CLI version $darcVersion...\"\n  Write-Host 'You may need to restart your command window if this is the first dotnet tool you have installed.'\n  if (-not $toolpath) {\n    Write-Host \"'$dotnet' tool install $darcCliPackageName --version $darcVersion --add-source '$arcadeServicesSource' -v $verbosity -g\"\n    & \"$dotnet\" tool install $darcCliPackageName --version $darcVersion --add-source \"$arcadeServicesSource\" -v $verbosity -g\n  }else {\n    Write-Host \"'$dotnet' tool install $darcCliPackageName --version $darcVersion --add-source '$arcadeServicesSource' -v $verbosity --tool-path '$toolpath'\"\n    & \"$dotnet\" tool install $darcCliPackageName --version $darcVersion --add-source \"$arcadeServicesSource\" -v $verbosity --tool-path \"$toolpath\"\n  }\n}\n\ntry {\n  InstallDarcCli $darcVersion $toolpath\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'Darc' -Message $_\n  ExitWithExitCode 1\n}"
  },
  {
    "path": "eng/common/darc-init.sh",
    "content": "#!/usr/bin/env bash\n\nsource=\"${BASH_SOURCE[0]}\"\ndarcVersion=''\nversionEndpoint='https://maestro.dot.net/api/assets/darc-version?api-version=2020-02-20'\nverbosity='minimal'\n\nwhile [[ $# > 0 ]]; do\n  opt=\"$(echo \"$1\" | tr \"[:upper:]\" \"[:lower:]\")\"\n  case \"$opt\" in\n    --darcversion)\n      darcVersion=$2\n      shift\n      ;;\n    --versionendpoint)\n      versionEndpoint=$2\n      shift\n      ;;\n    --verbosity)\n      verbosity=$2\n      shift\n      ;;\n    --toolpath)\n      toolpath=$2\n      shift\n      ;;\n    *)\n      echo \"Invalid argument: $1\"\n      usage\n      exit 1\n      ;;\n  esac\n\n  shift\ndone\n\n# resolve $source until the file is no longer a symlink\nwhile [[ -h \"$source\" ]]; do\n  scriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n  source=\"$(readlink \"$source\")\"\n  # if $source was a relative symlink, we need to resolve it relative to the path where the\n  # symlink file was located\n  [[ $source != /* ]] && source=\"$scriptroot/$source\"\ndone\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\n. \"$scriptroot/tools.sh\"\n\nif [ -z \"$darcVersion\" ]; then\n  darcVersion=$(curl -X GET \"$versionEndpoint\" -H \"accept: text/plain\")\nfi\n\nfunction InstallDarcCli {\n  local darc_cli_package_name=\"microsoft.dotnet.darc\"\n\n  InitializeDotNetCli true\n  local dotnet_root=$_InitializeDotNetCli\n\n  if [ -z \"$toolpath\" ]; then\n    local tool_list=$($dotnet_root/dotnet tool list -g)\n    if [[ $tool_list = *$darc_cli_package_name* ]]; then\n      echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name -g)\n    fi\n  else\n    local tool_list=$($dotnet_root/dotnet tool list --tool-path \"$toolpath\")\n    if [[ $tool_list = *$darc_cli_package_name* ]]; then\n      echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name --tool-path \"$toolpath\")\n    fi\n  fi\n\n  local arcadeServicesSource=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json\"\n\n  echo \"Installing Darc CLI version $darcVersion...\"\n  echo \"You may need to restart your command shell if this is the first dotnet tool you have installed.\"\n  if [ -z \"$toolpath\" ]; then\n    echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source \"$arcadeServicesSource\" -v $verbosity -g)\n  else\n    echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source \"$arcadeServicesSource\" -v $verbosity --tool-path \"$toolpath\")\n  fi\n}\n\nInstallDarcCli\n"
  },
  {
    "path": "eng/common/dotnet-install.cmd",
    "content": "@echo off\npowershell -ExecutionPolicy ByPass -NoProfile -command \"& \"\"\"%~dp0dotnet-install.ps1\"\"\" %*\""
  },
  {
    "path": "eng/common/dotnet-install.ps1",
    "content": "[CmdletBinding(PositionalBinding=$false)]\nParam(\n  [string] $verbosity = 'minimal',\n  [string] $architecture = '',\n  [string] $version = 'Latest',\n  [string] $runtime = 'dotnet',\n  [string] $RuntimeSourceFeed = '',\n  [string] $RuntimeSourceFeedKey = ''\n)\n\n. $PSScriptRoot\\tools.ps1\n\n$dotnetRoot = Join-Path $RepoRoot '.dotnet'\n\n$installdir = $dotnetRoot\ntry {\n    if ($architecture -and $architecture.Trim() -eq 'x86') {\n        $installdir = Join-Path $installdir 'x86'\n    }\n    InstallDotNet $installdir $version $architecture $runtime $true -RuntimeSourceFeed $RuntimeSourceFeed -RuntimeSourceFeedKey $RuntimeSourceFeedKey\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_\n  ExitWithExitCode 1\n}\n\nExitWithExitCode 0\n"
  },
  {
    "path": "eng/common/dotnet-install.sh",
    "content": "#!/usr/bin/env bash\n\nsource=\"${BASH_SOURCE[0]}\"\n# resolve $source until the file is no longer a symlink\nwhile [[ -h \"$source\" ]]; do\n  scriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n  source=\"$(readlink \"$source\")\"\n  # if $source was a relative symlink, we need to resolve it relative to the path where the\n  # symlink file was located\n  [[ $source != /* ]] && source=\"$scriptroot/$source\"\ndone\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\n. \"$scriptroot/tools.sh\"\n\nversion='Latest'\narchitecture=''\nruntime='dotnet'\nruntimeSourceFeed=''\nruntimeSourceFeedKey=''\nwhile [[ $# > 0 ]]; do\n  opt=\"$(echo \"$1\" | tr \"[:upper:]\" \"[:lower:]\")\"\n  case \"$opt\" in\n    -version|-v)\n      shift\n      version=\"$1\"\n      ;;\n    -architecture|-a)\n      shift\n      architecture=\"$1\"\n      ;;\n    -runtime|-r)\n      shift\n      runtime=\"$1\"\n      ;;\n    -runtimesourcefeed)\n      shift\n      runtimeSourceFeed=\"$1\"\n      ;;\n    -runtimesourcefeedkey)\n      shift\n      runtimeSourceFeedKey=\"$1\"\n      ;;\n    *)\n      Write-PipelineTelemetryError -Category 'Build' -Message \"Invalid argument: $1\"\n      exit 1\n      ;;\n  esac\n  shift\ndone\n\n# Use uname to determine what the CPU is, see https://en.wikipedia.org/wiki/Uname#Examples\ncpuname=$(uname -m)\ncase $cpuname in\n  arm64|aarch64)\n    buildarch=arm64\n    if [ \"$(getconf LONG_BIT)\" -lt 64 ]; then\n        # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)\n        buildarch=arm\n    fi\n    ;;\n  loongarch64)\n    buildarch=loongarch64\n    ;;\n  amd64|x86_64)\n    buildarch=x64\n    ;;\n  armv*l)\n    buildarch=arm\n    ;;\n  i[3-6]86)\n    buildarch=x86\n    ;;\n  riscv64)\n    buildarch=riscv64\n    ;;\n  *)\n    echo \"Unknown CPU $cpuname detected, treating it as x64\"\n    buildarch=x64\n    ;;\nesac\n\ndotnetRoot=\"${repo_root}.dotnet\"\nif [[ $architecture != \"\" ]] && [[ $architecture != $buildarch ]]; then\n  dotnetRoot=\"$dotnetRoot/$architecture\"\nfi\n\nInstallDotNet \"$dotnetRoot\" $version \"$architecture\" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey || {\n  local exit_code=$?\n  Write-PipelineTelemetryError -Category 'InitializeToolset' -Message \"dotnet-install.sh failed (exit code '$exit_code').\" >&2\n  ExitWithExitCode $exit_code\n}\n\nExitWithExitCode 0\n"
  },
  {
    "path": "eng/common/enable-cross-org-publishing.ps1",
    "content": "param(\n  [string] $token\n)\n\n\n. $PSScriptRoot\\pipeline-logging-functions.ps1\n\n# Write-PipelineSetVariable will no-op if a variable named $ci is not defined\n# Since this script is only ever called in AzDO builds, just universally set it\n$ci = $true\n\nWrite-PipelineSetVariable -Name 'VSS_NUGET_ACCESSTOKEN' -Value $token -IsMultiJobVariable $false\nWrite-PipelineSetVariable -Name 'VSS_NUGET_URI_PREFIXES' -Value 'https://dnceng.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/dnceng/;https://devdiv.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/devdiv/' -IsMultiJobVariable $false\n"
  },
  {
    "path": "eng/common/generate-locproject.ps1",
    "content": "Param(\n    [Parameter(Mandatory=$true)][string] $SourcesDirectory,     # Directory where source files live; if using a Localize directory it should live in here\n    [string] $LanguageSet = 'VS_Main_Languages',                # Language set to be used in the LocProject.json\n    [switch] $UseCheckedInLocProjectJson,                       # When set, generates a LocProject.json and compares it to one that already exists in the repo; otherwise just generates one\n    [switch] $CreateNeutralXlfs                                 # Creates neutral xlf files. Only set to false when running locally\n)\n\n# Generates LocProject.json files for the OneLocBuild task. OneLocBuildTask is described here:\n# https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task\n\nSet-StrictMode -Version 2.0\n$ErrorActionPreference = \"Stop\"\n. $PSScriptRoot\\pipeline-logging-functions.ps1\n\n$exclusionsFilePath = \"$SourcesDirectory\\eng\\Localize\\LocExclusions.json\"\n$exclusions = @{ Exclusions = @() }\nif (Test-Path -Path $exclusionsFilePath)\n{\n    $exclusions = Get-Content \"$exclusionsFilePath\" | ConvertFrom-Json\n}\n\nPush-Location \"$SourcesDirectory\" # push location for Resolve-Path -Relative to work\n\n# Template files\n$jsonFiles = @()\n$jsonTemplateFiles = Get-ChildItem -Recurse -Path \"$SourcesDirectory\" | Where-Object { $_.FullName -Match \"\\.template\\.config\\\\localize\\\\.+\\.en\\.json\" } # .NET templating pattern\n$jsonTemplateFiles | ForEach-Object {\n    $null = $_.Name -Match \"(.+)\\.[\\w-]+\\.json\" # matches '[filename].[langcode].json\n\n    $destinationFile = \"$($_.Directory.FullName)\\$($Matches.1).json\"\n    $jsonFiles += Copy-Item \"$($_.FullName)\" -Destination $destinationFile -PassThru\n}\n\n$jsonWinformsTemplateFiles = Get-ChildItem -Recurse -Path \"$SourcesDirectory\" | Where-Object { $_.FullName -Match \"en\\\\strings\\.json\" } # current winforms pattern\n\n$wxlFiles = Get-ChildItem -Recurse -Path \"$SourcesDirectory\" | Where-Object { $_.FullName -Match \"\\\\.+\\.wxl\" -And -Not( $_.Directory.Name -Match \"\\d{4}\" ) } # localized files live in four digit lang ID directories; this excludes them\nif (-not $wxlFiles) {\n    $wxlEnFiles = Get-ChildItem -Recurse -Path \"$SourcesDirectory\" | Where-Object { $_.FullName -Match \"\\\\1033\\\\.+\\.wxl\" } #  pick up en files (1033 = en) specifically so we can copy them to use as the neutral xlf files\n    if ($wxlEnFiles) {\n      $wxlFiles = @()\n      $wxlEnFiles | ForEach-Object {\n        $destinationFile = \"$($_.Directory.Parent.FullName)\\$($_.Name)\"\n        $wxlFiles += Copy-Item \"$($_.FullName)\" -Destination $destinationFile -PassThru\n      }\n    }\n}\n\n$macosHtmlEnFiles = Get-ChildItem -Recurse -Path \"$SourcesDirectory\" | Where-Object { $_.FullName -Match \"en\\.lproj\\\\.+\\.html$\" } # add installer HTML files\n$macosHtmlFiles = @()\nif ($macosHtmlEnFiles) {\n    $macosHtmlEnFiles | ForEach-Object {\n        $destinationFile = \"$($_.Directory.Parent.FullName)\\$($_.Name)\"\n        $macosHtmlFiles += Copy-Item \"$($_.FullName)\" -Destination $destinationFile -PassThru\n    }\n}\n\n$xlfFiles = @()\n\n$allXlfFiles = Get-ChildItem -Recurse -Path \"$SourcesDirectory\\*\\*.xlf\"\n$langXlfFiles = @()\nif ($allXlfFiles) {\n    $null = $allXlfFiles[0].FullName -Match \"\\.([\\w-]+)\\.xlf\" # matches '[langcode].xlf'\n    $firstLangCode = $Matches.1\n    $langXlfFiles = Get-ChildItem -Recurse -Path \"$SourcesDirectory\\*\\*.$firstLangCode.xlf\"\n}\n$langXlfFiles | ForEach-Object {\n    $null = $_.Name -Match \"(.+)\\.[\\w-]+\\.xlf\" # matches '[filename].[langcode].xlf\n\n    $destinationFile = \"$($_.Directory.FullName)\\$($Matches.1).xlf\"\n    $xlfFiles += Copy-Item \"$($_.FullName)\" -Destination $destinationFile -PassThru\n}\n\n$locFiles = $jsonFiles + $jsonWinformsTemplateFiles + $xlfFiles\n\n$locJson = @{\n    Projects = @(\n        @{\n            LanguageSet = $LanguageSet\n            LocItems = @(\n                $locFiles | ForEach-Object {\n                    $outputPath = \"$(($_.DirectoryName | Resolve-Path -Relative) + \"\\\")\"\n                    $continue = $true\n                    foreach ($exclusion in $exclusions.Exclusions) {\n                        if ($_.FullName.Contains($exclusion))\n                        {\n                            $continue = $false\n                        }\n                    }\n                    $sourceFile = ($_.FullName | Resolve-Path -Relative)\n                    if (!$CreateNeutralXlfs -and $_.Extension -eq '.xlf') {\n                        Remove-Item -Path $sourceFile\n                    }\n                    if ($continue)\n                    {\n                        if ($_.Directory.Name -eq 'en' -and $_.Extension -eq '.json') {\n                            return @{\n                                SourceFile = $sourceFile\n                                CopyOption = \"LangIDOnPath\"\n                                OutputPath = \"$($_.Directory.Parent.FullName | Resolve-Path -Relative)\\\"\n                            }\n                        } else {\n                            return @{\n                                SourceFile = $sourceFile\n                                CopyOption = \"LangIDOnName\"\n                                OutputPath = $outputPath\n                            }\n                        }\n                    }\n                }\n            )\n        },\n        @{\n            LanguageSet = $LanguageSet\n            CloneLanguageSet = \"WiX_CloneLanguages\"\n            LssFiles = @( \"wxl_loc.lss\" )\n            LocItems = @(\n                $wxlFiles | ForEach-Object {\n                    $outputPath = \"$($_.Directory.FullName | Resolve-Path -Relative)\\\"\n                    $continue = $true\n                    foreach ($exclusion in $exclusions.Exclusions) {\n                        if ($_.FullName.Contains($exclusion)) {\n                            $continue = $false\n                        }\n                    }\n                    $sourceFile = ($_.FullName | Resolve-Path -Relative)\n                    if ($continue)\n                    {\n                        return @{\n                            SourceFile = $sourceFile\n                            CopyOption = \"LangIDOnPath\"\n                            OutputPath = $outputPath\n                        }\n                    }\n                }\n            )\n        },\n        @{\n            LanguageSet = $LanguageSet\n            CloneLanguageSet = \"VS_macOS_CloneLanguages\"\n            LssFiles = @( \".\\eng\\common\\loc\\P22DotNetHtmlLocalization.lss\" )\n            LocItems = @(\n                $macosHtmlFiles | ForEach-Object {\n                    $outputPath = \"$($_.Directory.FullName | Resolve-Path -Relative)\\\"\n                    $continue = $true\n                    foreach ($exclusion in $exclusions.Exclusions) {\n                        if ($_.FullName.Contains($exclusion)) {\n                            $continue = $false\n                        }\n                    }\n                    $sourceFile = ($_.FullName | Resolve-Path -Relative)\n                    $lciFile = $sourceFile + \".lci\"\n                    if ($continue) {\n                        $result = @{\n                            SourceFile = $sourceFile\n                            CopyOption = \"LangIDOnPath\"\n                            OutputPath = $outputPath\n                        }\n                        if (Test-Path $lciFile -PathType Leaf) {\n                            $result[\"LciFile\"] = $lciFile\n                        }\n                        return $result\n                    }\n                }\n            )\n        }\n    )\n}\n\n$json = ConvertTo-Json $locJson -Depth 5\nWrite-Host \"LocProject.json generated:`n`n$json`n`n\"\nPop-Location\n\nif (!$UseCheckedInLocProjectJson) {\n    New-Item \"$SourcesDirectory\\eng\\Localize\\LocProject.json\" -Force # Need this to make sure the Localize directory is created\n    Set-Content \"$SourcesDirectory\\eng\\Localize\\LocProject.json\" $json\n}\nelse {\n    New-Item \"$SourcesDirectory\\eng\\Localize\\LocProject-generated.json\" -Force # Need this to make sure the Localize directory is created\n    Set-Content \"$SourcesDirectory\\eng\\Localize\\LocProject-generated.json\" $json\n\n    if ((Get-FileHash \"$SourcesDirectory\\eng\\Localize\\LocProject-generated.json\").Hash -ne (Get-FileHash \"$SourcesDirectory\\eng\\Localize\\LocProject.json\").Hash) {\n        Write-PipelineTelemetryError -Category \"OneLocBuild\" -Message \"Existing LocProject.json differs from generated LocProject.json. Download LocProject-generated.json and compare them.\"\n\n        exit 1\n    }\n    else {\n        Write-Host \"Generated LocProject.json and current LocProject.json are identical.\"\n    }\n}\n"
  },
  {
    "path": "eng/common/generate-sbom-prep.ps1",
    "content": "Param(\n    [Parameter(Mandatory=$true)][string] $ManifestDirPath    # Manifest directory where sbom will be placed\n)\n\n. $PSScriptRoot\\pipeline-logging-functions.ps1\n\nWrite-Host \"Creating dir $ManifestDirPath\"\n# create directory for sbom manifest to be placed\nif (!(Test-Path -path $ManifestDirPath))\n{\n  New-Item -ItemType Directory -path $ManifestDirPath\n  Write-Host \"Successfully created directory $ManifestDirPath\"\n}\nelse{\n  Write-PipelineTelemetryError -category 'Build'  \"Unable to create sbom folder.\"\n}\n\nWrite-Host \"Updating artifact name\"\n$artifact_name = \"${env:SYSTEM_STAGENAME}_${env:AGENT_JOBNAME}_SBOM\" -replace '[\"/:<>\\\\|?@*\"() ]', '_'\nWrite-Host \"Artifact name $artifact_name\"\nWrite-Host \"##vso[task.setvariable variable=ARTIFACT_NAME]$artifact_name\"\n"
  },
  {
    "path": "eng/common/generate-sbom-prep.sh",
    "content": "#!/usr/bin/env bash\n\nsource=\"${BASH_SOURCE[0]}\"\n\n# resolve $SOURCE until the file is no longer a symlink\nwhile [[ -h $source ]]; do\n  scriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n  source=\"$(readlink \"$source\")\"\n\n  # if $source was a relative symlink, we need to resolve it relative to the path where the\n  # symlink file was located\n  [[ $source != /* ]] && source=\"$scriptroot/$source\"\ndone\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n. $scriptroot/pipeline-logging-functions.sh\n\nmanifest_dir=$1\n\nif [ ! -d \"$manifest_dir\" ] ; then\n  mkdir -p \"$manifest_dir\"\n  echo \"Sbom directory created.\" $manifest_dir\nelse\n  Write-PipelineTelemetryError -category 'Build'  \"Unable to create sbom folder.\"\nfi\n\nartifact_name=$SYSTEM_STAGENAME\"_\"$AGENT_JOBNAME\"_SBOM\"\necho \"Artifact name before : \"$artifact_name\n# replace all special characters with _, some builds use special characters like : in Agent.Jobname, that is not a permissible name while uploading artifacts.\nsafe_artifact_name=\"${artifact_name//[\"/:<>\\\\|?@*$\" ]/_}\"\necho \"Artifact name after : \"$safe_artifact_name\nexport ARTIFACT_NAME=$safe_artifact_name\necho \"##vso[task.setvariable variable=ARTIFACT_NAME]$safe_artifact_name\"\n\nexit 0\n"
  },
  {
    "path": "eng/common/helixpublish.proj",
    "content": "<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. -->\n<Project Sdk=\"Microsoft.DotNet.Helix.Sdk\" DefaultTargets=\"Test\">\n\n  <PropertyGroup>\n    <Language>msbuild</Language>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <HelixCorrelationPayload Include=\"$(CorrelationPayloadDirectory)\">\n      <PayloadDirectory>%(Identity)</PayloadDirectory>\n    </HelixCorrelationPayload>\n  </ItemGroup>\n\n  <ItemGroup>\n    <HelixWorkItem Include=\"WorkItem\" Condition=\"'$(WorkItemDirectory)' != ''\">\n      <PayloadDirectory>$(WorkItemDirectory)</PayloadDirectory>\n      <Command>$(WorkItemCommand)</Command>\n      <Timeout Condition=\"'$(WorkItemTimeout)' != ''\">$(WorkItemTimeout)</Timeout>\n    </HelixWorkItem>\n  </ItemGroup>\n\n  <ItemGroup>\n    <XUnitProject Include=\"$(XUnitProjects.Split(';'))\">\n      <Arguments />\n    </XUnitProject>\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "eng/common/init-tools-native.cmd",
    "content": "@echo off\npowershell -NoProfile -NoLogo -ExecutionPolicy ByPass -command \"& \"\"\"%~dp0init-tools-native.ps1\"\"\" %*\"\nexit /b %ErrorLevel%"
  },
  {
    "path": "eng/common/init-tools-native.ps1",
    "content": "<#\n.SYNOPSIS\nEntry point script for installing native tools\n\n.DESCRIPTION\nReads $RepoRoot\\global.json file to determine native assets to install\nand executes installers for those tools\n\n.PARAMETER BaseUri\nBase file directory or Url from which to acquire tool archives\n\n.PARAMETER InstallDirectory\nDirectory to install native toolset.  This is a command-line override for the default\nInstall directory precedence order:\n- InstallDirectory command-line override\n- NETCOREENG_INSTALL_DIRECTORY environment variable\n- (default) %USERPROFILE%/.netcoreeng/native\n\n.PARAMETER Clean\nSwitch specifying to not install anything, but cleanup native asset folders\n\n.PARAMETER Force\nClean and then install tools\n\n.PARAMETER DownloadRetries\nTotal number of retry attempts\n\n.PARAMETER RetryWaitTimeInSeconds\nWait time between retry attempts in seconds\n\n.PARAMETER GlobalJsonFile\nFile path to global.json file\n\n.PARAMETER PathPromotion\nOptional switch to enable either promote native tools specified in the global.json to the path (in Azure Pipelines)\nor break the build if a native tool is not found on the path (on a local dev machine)\n\n.NOTES\n#>\n[CmdletBinding(PositionalBinding=$false)]\nParam (\n  [string] $BaseUri = 'https://netcorenativeassets.blob.core.windows.net/resource-packages/external',\n  [string] $InstallDirectory,\n  [switch] $Clean = $False,\n  [switch] $Force = $False,\n  [int] $DownloadRetries = 5,\n  [int] $RetryWaitTimeInSeconds = 30,\n  [string] $GlobalJsonFile,\n  [switch] $PathPromotion\n)\n\nif (!$GlobalJsonFile) {\n  $GlobalJsonFile = Join-Path (Get-Item $PSScriptRoot).Parent.Parent.FullName 'global.json'\n}\n\nSet-StrictMode -version 2.0\n$ErrorActionPreference='Stop'\n\n. $PSScriptRoot\\pipeline-logging-functions.ps1\nImport-Module -Name (Join-Path $PSScriptRoot 'native\\CommonLibrary.psm1')\n\ntry {\n  # Define verbose switch if undefined\n  $Verbose = $VerbosePreference -Eq 'Continue'\n\n  $EngCommonBaseDir = Join-Path $PSScriptRoot 'native\\'\n  $NativeBaseDir = $InstallDirectory\n  if (!$NativeBaseDir) {\n    $NativeBaseDir = CommonLibrary\\Get-NativeInstallDirectory\n  }\n  $Env:CommonLibrary_NativeInstallDir = $NativeBaseDir\n  $InstallBin = Join-Path $NativeBaseDir 'bin'\n  $InstallerPath = Join-Path $EngCommonBaseDir 'install-tool.ps1'\n\n  # Process tools list\n  Write-Host \"Processing $GlobalJsonFile\"\n  If (-Not (Test-Path $GlobalJsonFile)) {\n    Write-Host \"Unable to find '$GlobalJsonFile'\"\n    exit 0\n  }\n  $NativeTools = Get-Content($GlobalJsonFile) -Raw |\n                    ConvertFrom-Json |\n                    Select-Object -Expand 'native-tools' -ErrorAction SilentlyContinue\n  if ($NativeTools) {\n    if ($PathPromotion -eq $True) {\n      $ArcadeToolsDirectory = \"$env:SYSTEMDRIVE\\arcade-tools\"\n      if (Test-Path $ArcadeToolsDirectory) { # if this directory exists, we should use native tools on machine\n        $NativeTools.PSObject.Properties | ForEach-Object {\n          $ToolName = $_.Name\n          $ToolVersion = $_.Value\n          $InstalledTools = @{}\n\n          if ((Get-Command \"$ToolName\" -ErrorAction SilentlyContinue) -eq $null) {\n            if ($ToolVersion -eq \"latest\") {\n              $ToolVersion = \"\"\n            }\n            $ToolDirectories = (Get-ChildItem -Path \"$ArcadeToolsDirectory\" -Filter \"$ToolName-$ToolVersion*\" | Sort-Object -Descending)\n            if ($ToolDirectories -eq $null) {\n              Write-Error \"Unable to find directory for $ToolName $ToolVersion; please make sure the tool is installed on this image.\"\n              exit 1\n            }\n            $ToolDirectory = $ToolDirectories[0]\n            $BinPathFile = \"$($ToolDirectory.FullName)\\binpath.txt\"\n            if (-not (Test-Path -Path \"$BinPathFile\")) {\n              Write-Error \"Unable to find binpath.txt in '$($ToolDirectory.FullName)' ($ToolName $ToolVersion); artifact is either installed incorrectly or is not a bootstrappable tool.\"\n              exit 1\n            }\n            $BinPath = Get-Content \"$BinPathFile\"\n            $ToolPath = Convert-Path -Path $BinPath\n            Write-Host \"Adding $ToolName to the path ($ToolPath)...\"\n            Write-Host \"##vso[task.prependpath]$ToolPath\"\n            $env:PATH = \"$ToolPath;$env:PATH\"\n            $InstalledTools += @{ $ToolName = $ToolDirectory.FullName }\n          }\n        }\n        return $InstalledTools\n      } else {\n        $NativeTools.PSObject.Properties | ForEach-Object {\n          $ToolName = $_.Name\n          $ToolVersion = $_.Value\n\n          if ((Get-Command \"$ToolName\" -ErrorAction SilentlyContinue) -eq $null) {\n            Write-PipelineTelemetryError -Category 'NativeToolsBootstrap' -Message \"$ToolName not found on path. Please install $ToolName $ToolVersion before proceeding.\"\n            Write-PipelineTelemetryError -Category 'NativeToolsBootstrap' -Message \"If this is running on a build machine, the arcade-tools directory was not found, which means there's an error with the image.\"\n          }\n        }\n        exit 0\n      }\n    } else {\n      $NativeTools.PSObject.Properties | ForEach-Object {\n        $ToolName = $_.Name\n        $ToolVersion = $_.Value\n        $LocalInstallerArguments =  @{ ToolName = \"$ToolName\" }\n        $LocalInstallerArguments += @{ InstallPath = \"$InstallBin\" }\n        $LocalInstallerArguments += @{ BaseUri = \"$BaseUri\" }\n        $LocalInstallerArguments += @{ CommonLibraryDirectory = \"$EngCommonBaseDir\" }\n        $LocalInstallerArguments += @{ Version = \"$ToolVersion\" }\n  \n        if ($Verbose) {\n          $LocalInstallerArguments += @{ Verbose = $True }\n        }\n        if (Get-Variable 'Force' -ErrorAction 'SilentlyContinue') {\n          if($Force) {\n            $LocalInstallerArguments += @{ Force = $True }\n          }\n        }\n        if ($Clean) {\n          $LocalInstallerArguments += @{ Clean = $True }\n        }\n  \n        Write-Verbose \"Installing $ToolName version $ToolVersion\"\n        Write-Verbose \"Executing '$InstallerPath $($LocalInstallerArguments.Keys.ForEach({\"-$_ '$($LocalInstallerArguments.$_)'\"}) -join ' ')'\"\n        & $InstallerPath @LocalInstallerArguments\n        if ($LASTEXITCODE -Ne \"0\") {\n          $errMsg = \"$ToolName installation failed\"\n          if ((Get-Variable 'DoNotAbortNativeToolsInstallationOnFailure' -ErrorAction 'SilentlyContinue') -and $DoNotAbortNativeToolsInstallationOnFailure) {\n              $showNativeToolsWarning = $true\n              if ((Get-Variable 'DoNotDisplayNativeToolsInstallationWarnings' -ErrorAction 'SilentlyContinue') -and $DoNotDisplayNativeToolsInstallationWarnings) {\n                  $showNativeToolsWarning = $false\n              }\n              if ($showNativeToolsWarning) {\n                  Write-Warning $errMsg\n              }\n              $toolInstallationFailure = $true\n          } else {\n              # We cannot change this to Write-PipelineTelemetryError because of https://github.com/dotnet/arcade/issues/4482\n              Write-Host $errMsg\n              exit 1\n          }\n        }\n      }\n  \n      if ((Get-Variable 'toolInstallationFailure' -ErrorAction 'SilentlyContinue') -and $toolInstallationFailure) {\n          # We cannot change this to Write-PipelineTelemetryError because of https://github.com/dotnet/arcade/issues/4482\n          Write-Host 'Native tools bootstrap failed'\n          exit 1\n      }\n    }\n  }\n  else {\n    Write-Host 'No native tools defined in global.json'\n    exit 0\n  }\n\n  if ($Clean) {\n    exit 0\n  }\n  if (Test-Path $InstallBin) {\n    Write-Host 'Native tools are available from ' (Convert-Path -Path $InstallBin)\n    Write-Host \"##vso[task.prependpath]$(Convert-Path -Path $InstallBin)\"\n    return $InstallBin\n  }\n  elseif (-not ($PathPromotion)) {\n    Write-PipelineTelemetryError -Category 'NativeToolsBootstrap' -Message 'Native tools install directory does not exist, installation failed'\n    exit 1\n  }\n  exit 0\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'NativeToolsBootstrap' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/init-tools-native.sh",
    "content": "#!/usr/bin/env bash\n\nsource=\"${BASH_SOURCE[0]}\"\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\nbase_uri='https://netcorenativeassets.blob.core.windows.net/resource-packages/external'\ninstall_directory=''\nclean=false\nforce=false\ndownload_retries=5\nretry_wait_time_seconds=30\nglobal_json_file=\"$(dirname \"$(dirname \"${scriptroot}\")\")/global.json\"\ndeclare -a native_assets\n\n. $scriptroot/pipeline-logging-functions.sh\n. $scriptroot/native/common-library.sh\n\nwhile (($# > 0)); do\n  lowerI=\"$(echo $1 | tr \"[:upper:]\" \"[:lower:]\")\"\n  case $lowerI in\n    --baseuri)\n      base_uri=$2\n      shift 2\n      ;;\n    --installdirectory)\n      install_directory=$2\n      shift 2\n      ;;\n    --clean)\n      clean=true\n      shift 1\n      ;;\n    --force)\n      force=true\n      shift 1\n      ;;\n    --donotabortonfailure)\n      donotabortonfailure=true\n      shift 1\n      ;;\n    --donotdisplaywarnings)\n      donotdisplaywarnings=true\n      shift 1\n      ;;\n    --downloadretries)\n      download_retries=$2\n      shift 2\n      ;;\n    --retrywaittimeseconds)\n      retry_wait_time_seconds=$2\n      shift 2\n      ;;\n    --help)\n      echo \"Common settings:\"\n      echo \"  --installdirectory                  Directory to install native toolset.\"\n      echo \"                                      This is a command-line override for the default\"\n      echo \"                                      Install directory precedence order:\"\n      echo \"                                          - InstallDirectory command-line override\"\n      echo \"                                          - NETCOREENG_INSTALL_DIRECTORY environment variable\"\n      echo \"                                          - (default) %USERPROFILE%/.netcoreeng/native\"\n      echo \"\"\n      echo \"  --clean                             Switch specifying not to install anything, but cleanup native asset folders\"\n      echo \"  --donotabortonfailure               Switch specifiying whether to abort native tools installation on failure\"\n      echo \"  --donotdisplaywarnings              Switch specifiying whether to display warnings during native tools installation on failure\"\n      echo \"  --force                             Clean and then install tools\"\n      echo \"  --help                              Print help and exit\"\n      echo \"\"\n      echo \"Advanced settings:\"\n      echo \"  --baseuri <value>                   Base URI for where to download native tools from\"\n      echo \"  --downloadretries <value>           Number of times a download should be attempted\"\n      echo \"  --retrywaittimeseconds <value>      Wait time between download attempts\"\n      echo \"\"\n      exit 0\n      ;;\n  esac\ndone\n\nfunction ReadGlobalJsonNativeTools {\n  # happy path: we have a proper JSON parsing tool `jq(1)` in PATH!\n  if command -v jq &> /dev/null; then\n\n    # jq: read each key/value pair under \"native-tools\" entry and emit:\n    #   KEY=\"<entry-key>\" VALUE=\"<entry-value>\"\n    # followed by a null byte.\n    #\n    # bash: read line with null byte delimeter and push to array (for later `eval`uation).\n\n    while IFS= read -rd '' line; do\n      native_assets+=(\"$line\")\n    done < <(jq -r '. |\n        select(has(\"native-tools\")) |\n        .\"native-tools\" |\n        keys[] as $k |\n        @sh \"KEY=\\($k) VALUE=\\(.[$k])\\u0000\"' \"$global_json_file\")\n\n    return\n  fi\n\n  # Warning: falling back to manually parsing JSON, which is not recommended.\n\n  # Following routine matches the output and escaping logic of jq(1)'s @sh formatter used above.\n  # It has been tested with several weird strings with escaped characters in entries (key and value)\n  # and results were compared with the output of jq(1) in binary representation using xxd(1);\n  # just before the assignment to 'native_assets' array (above and below).\n\n  # try to capture the section under \"native-tools\".\n  if [[ ! \"$(cat \"$global_json_file\")\" =~ \\\"native-tools\\\"[[:space:]\\:\\{]*([^\\}]+) ]]; then\n    return\n  fi\n\n  section=\"${BASH_REMATCH[1]}\"\n\n  parseStarted=0\n  possibleEnd=0\n  escaping=0\n  escaped=0\n  isKey=1\n\n  for (( i=0; i<${#section}; i++ )); do\n    char=\"${section:$i:1}\"\n    if ! ((parseStarted)) && [[ \"$char\" =~ [[:space:],:] ]]; then continue; fi\n\n    if ! ((escaping)) && [[ \"$char\" == \"\\\\\" ]]; then\n      escaping=1\n    elif ((escaping)) && ! ((escaped)); then\n      escaped=1\n    fi\n\n    if ! ((parseStarted)) && [[ \"$char\" == \"\\\"\" ]]; then\n      parseStarted=1\n      possibleEnd=0\n    elif [[ \"$char\" == \"'\" ]]; then\n      token=\"$token'\\\\\\''\"\n      possibleEnd=0\n    elif ((escaping)) || [[ \"$char\" != \"\\\"\" ]]; then\n      token=\"$token$char\"\n      possibleEnd=1\n    fi\n\n    if ((possibleEnd)) && ! ((escaping)) && [[ \"$char\" == \"\\\"\" ]]; then\n      # Use printf to unescape token to match jq(1)'s @sh formatting rules.\n      # do not use 'token=\"$(printf \"$token\")\"' syntax, as $() eats the trailing linefeed.\n      printf -v token \"'$token'\"\n\n      if ((isKey)); then\n        KEY=\"$token\"\n        isKey=0\n      else\n        line=\"KEY=$KEY VALUE=$token\"\n        native_assets+=(\"$line\")\n        isKey=1\n      fi\n\n      # reset for next token\n      parseStarted=0\n      token=\n    elif ((escaping)) && ((escaped)); then\n      escaping=0\n      escaped=0\n    fi\n  done\n}\n\nnative_base_dir=$install_directory\nif [[ -z $install_directory ]]; then\n  native_base_dir=$(GetNativeInstallDirectory)\nfi\n\ninstall_bin=\"${native_base_dir}/bin\"\ninstalled_any=false\n\nReadGlobalJsonNativeTools\n\nif [[ ${#native_assets[@]} -eq 0 ]]; then\n  echo \"No native tools defined in global.json\"\n  exit 0;\nelse\n  native_installer_dir=\"$scriptroot/native\"\n  for index in \"${!native_assets[@]}\"; do\n    eval \"${native_assets[\"$index\"]}\"\n\n    installer_path=\"$native_installer_dir/install-$KEY.sh\"\n    installer_command=\"$installer_path\"\n    installer_command+=\" --baseuri $base_uri\"\n    installer_command+=\" --installpath $install_bin\"\n    installer_command+=\" --version $VALUE\"\n    echo $installer_command\n\n    if [[ $force = true ]]; then\n      installer_command+=\" --force\"\n    fi\n\n    if [[ $clean = true ]]; then\n      installer_command+=\" --clean\"\n    fi\n\n    if [[ -a $installer_path ]]; then\n      $installer_command\n      if [[ $? != 0 ]]; then\n        if [[ $donotabortonfailure = true ]]; then\n          if [[ $donotdisplaywarnings != true ]]; then\n            Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Execution Failed\"\n          fi\n        else\n          Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Execution Failed\"\n          exit 1\n        fi\n      else\n        $installed_any = true\n      fi\n    else\n      if [[ $donotabortonfailure == true ]]; then\n        if [[ $donotdisplaywarnings != true ]]; then\n          Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Execution Failed: no install script\"\n        fi\n      else\n        Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Execution Failed: no install script\"\n        exit 1\n      fi\n    fi\n  done\nfi\n\nif [[ $clean = true ]]; then\n  exit 0\nfi\n\nif [[ -d $install_bin ]]; then\n  echo \"Native tools are available from $install_bin\"\n  echo \"##vso[task.prependpath]$install_bin\"\nelse\n  if [[ $installed_any = true ]]; then\n    Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Native tools install directory does not exist, installation failed\"\n    exit 1\n  fi\nfi\n\nexit 0\n"
  },
  {
    "path": "eng/common/internal/Directory.Build.props",
    "content": "<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. -->\n<Project>\n\n  <PropertyGroup>\n    <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>\n    <ImportDirectoryPackagesProps>false</ImportDirectoryPackagesProps>\n  </PropertyGroup>\n\n  <Import Project=\"Sdk.props\" Sdk=\"Microsoft.DotNet.Arcade.Sdk\" />\n\n</Project>\n"
  },
  {
    "path": "eng/common/internal/NuGet.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <clear />\n    <add key=\"dotnet-core-internal-tooling\" value=\"https://pkgs.dev.azure.com/devdiv/_packaging/dotnet-core-internal-tooling/nuget/v3/index.json\" />\n  </packageSources>\n</configuration>\n"
  },
  {
    "path": "eng/common/internal/Tools.csproj",
    "content": "<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. -->\n<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net472</TargetFramework>\n    <AutomaticallyUseReferenceAssemblyPackages>false</AutomaticallyUseReferenceAssemblyPackages>\n    <BuildWithNetFrameworkHostedCompiler>false</BuildWithNetFrameworkHostedCompiler>\n  </PropertyGroup>\n  <ItemGroup>\n    <!-- Clear references, the SDK may add some depending on UsuingToolXxx settings, but we only want to restore the following -->\n    <PackageReference Remove=\"@(PackageReference)\"/>\n    <PackageReference Include=\"Microsoft.ManifestTool.CrossPlatform\" Version=\"$(MicrosoftManifestToolCrossPlatformVersion)\" />\n    <PackageReference Include=\"Microsoft.VisualStudioEng.MicroBuild.Core\" Version=\"$(MicrosoftVisualStudioEngMicroBuildCoreVersion)\" />\n    <PackageReference Include=\"Microsoft.VisualStudioEng.MicroBuild.Plugins.SwixBuild\" Version=\"$(MicrosoftVisualStudioEngMicroBuildPluginsSwixBuildVersion)\" />\n    <PackageReference Include=\"Microsoft.DotNet.IBCMerge\" Version=\"$(MicrosoftDotNetIBCMergeVersion)\" Condition=\"'$(UsingToolIbcOptimization)' == 'true'\" />\n    <PackageReference Include=\"Drop.App\" Version=\"$(DropAppVersion)\" ExcludeAssets=\"all\" Condition=\"'$(UsingToolVisualStudioIbcTraining)' == 'true'\"/>\n  </ItemGroup>\n  <PropertyGroup>\n    <RestoreSources></RestoreSources>\n    <RestoreSources Condition=\"'$(UsingToolIbcOptimization)' == 'true'\">\n      https://devdiv.pkgs.visualstudio.com/_packaging/dotnet-core-internal-tooling/nuget/v3/index.json;\n    </RestoreSources>\n    <RestoreSources Condition=\"'$(UsingToolVisualStudioIbcTraining)' == 'true'\">\n      $(RestoreSources);\n      https://devdiv.pkgs.visualstudio.com/_packaging/VS/nuget/v3/index.json;\n    </RestoreSources>\n  </PropertyGroup>\n\n  <!-- Repository extensibility point -->\n  <Import Project=\"$(RepositoryEngineeringDir)InternalTools.props\" Condition=\"Exists('$(RepositoryEngineeringDir)InternalTools.props')\" />\n\n</Project>\n"
  },
  {
    "path": "eng/common/internal-feed-operations.ps1",
    "content": "param(\n  [Parameter(Mandatory=$true)][string] $Operation,\n  [string] $AuthToken,\n  [string] $CommitSha,\n  [string] $RepoName,\n  [switch] $IsFeedPrivate\n)\n\n$ErrorActionPreference = 'Stop'\nSet-StrictMode -Version 2.0\n. $PSScriptRoot\\tools.ps1\n\n# Sets VSS_NUGET_EXTERNAL_FEED_ENDPOINTS based on the \"darc-int-*\" feeds defined in NuGet.config. This is needed\n# in build agents by CredProvider to authenticate the restore requests to internal feeds as specified in\n# https://github.com/microsoft/artifacts-credprovider/blob/0f53327cd12fd893d8627d7b08a2171bf5852a41/README.md#environment-variables. This should ONLY be called from identified\n# internal builds\nfunction SetupCredProvider {\n  param(\n    [string] $AuthToken\n  )    \n\n  # Install the Cred Provider NuGet plugin\n  Write-Host 'Setting up Cred Provider NuGet plugin in the agent...'\n  Write-Host \"Getting 'installcredprovider.ps1' from 'https://github.com/microsoft/artifacts-credprovider'...\"\n\n  $url = 'https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1'\n  \n  Write-Host \"Writing the contents of 'installcredprovider.ps1' locally...\"\n  Invoke-WebRequest $url -OutFile installcredprovider.ps1\n  \n  Write-Host 'Installing plugin...'\n  .\\installcredprovider.ps1 -Force\n  \n  Write-Host \"Deleting local copy of 'installcredprovider.ps1'...\"\n  Remove-Item .\\installcredprovider.ps1\n\n  if (-Not(\"$env:USERPROFILE\\.nuget\\plugins\\netcore\")) {\n    Write-PipelineTelemetryError -Category 'Arcade' -Message 'CredProvider plugin was not installed correctly!'\n    ExitWithExitCode 1  \n  } \n  else {\n    Write-Host 'CredProvider plugin was installed correctly!'\n  }\n\n  # Then, we set the 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS' environment variable to restore from the stable \n  # feeds successfully\n\n  $nugetConfigPath = Join-Path $RepoRoot \"NuGet.config\"\n\n  if (-Not (Test-Path -Path $nugetConfigPath)) {\n    Write-PipelineTelemetryError -Category 'Build' -Message 'NuGet.config file not found in repo root!'\n    ExitWithExitCode 1\n  }\n  \n  $endpoints = New-Object System.Collections.ArrayList\n  $nugetConfigPackageSources = Select-Xml -Path $nugetConfigPath -XPath \"//packageSources/add[contains(@key, 'darc-int-')]/@value\" | foreach{$_.Node.Value}\n  \n  if (($nugetConfigPackageSources | Measure-Object).Count -gt 0 ) {\n    foreach ($stableRestoreResource in $nugetConfigPackageSources) {\n      $trimmedResource = ([string]$stableRestoreResource).Trim()\n      [void]$endpoints.Add(@{endpoint=\"$trimmedResource\"; password=\"$AuthToken\"}) \n    }\n  }\n\n  if (($endpoints | Measure-Object).Count -gt 0) {\n      $endpointCredentials = @{endpointCredentials=$endpoints} | ConvertTo-Json -Compress\n\n     # Create the environment variables the AzDo way\n      Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data $endpointCredentials -Properties @{\n        'variable' = 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS'\n        'issecret' = 'false'\n      } \n\n      # We don't want sessions cached since we will be updating the endpoints quite frequently\n      Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data 'False' -Properties @{\n        'variable' = 'NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED'\n        'issecret' = 'false'\n      } \n  }\n  else\n  {\n    Write-Host 'No internal endpoints found in NuGet.config'\n  }\n}\n\n#Workaround for https://github.com/microsoft/msbuild/issues/4430\nfunction InstallDotNetSdkAndRestoreArcade {\n  $dotnetTempDir = Join-Path $RepoRoot \"dotnet\"\n  $dotnetSdkVersion=\"2.1.507\" # After experimentation we know this version works when restoring the SDK (compared to 3.0.*)\n  $dotnet = \"$dotnetTempDir\\dotnet.exe\"\n  $restoreProjPath = \"$PSScriptRoot\\restore.proj\"\n  \n  Write-Host \"Installing dotnet SDK version $dotnetSdkVersion to restore Arcade SDK...\"\n  InstallDotNetSdk \"$dotnetTempDir\" \"$dotnetSdkVersion\"\n  \n  '<Project Sdk=\"Microsoft.DotNet.Arcade.Sdk\"/>' | Out-File \"$restoreProjPath\"\n\n  & $dotnet restore $restoreProjPath\n\n  Write-Host 'Arcade SDK restored!'\n\n  if (Test-Path -Path $restoreProjPath) {\n    Remove-Item $restoreProjPath\n  }\n\n  if (Test-Path -Path $dotnetTempDir) {\n    Remove-Item $dotnetTempDir -Recurse\n  }\n}\n\ntry {\n  Push-Location $PSScriptRoot\n\n  if ($Operation -like 'setup') {\n    SetupCredProvider $AuthToken\n  } \n  elseif ($Operation -like 'install-restore') {\n    InstallDotNetSdkAndRestoreArcade\n  }\n  else {\n    Write-PipelineTelemetryError -Category 'Arcade' -Message \"Unknown operation '$Operation'!\"\n    ExitWithExitCode 1  \n  }\n} \ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'Arcade' -Message $_\n  ExitWithExitCode 1\n} \nfinally {\n  Pop-Location\n}\n"
  },
  {
    "path": "eng/common/internal-feed-operations.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\n# Sets VSS_NUGET_EXTERNAL_FEED_ENDPOINTS based on the \"darc-int-*\" feeds defined in NuGet.config. This is needed\n# in build agents by CredProvider to authenticate the restore requests to internal feeds as specified in\n# https://github.com/microsoft/artifacts-credprovider/blob/0f53327cd12fd893d8627d7b08a2171bf5852a41/README.md#environment-variables. \n# This should ONLY be called from identified internal builds\nfunction SetupCredProvider {\n  local authToken=$1\n  \n  # Install the Cred Provider NuGet plugin\n  echo \"Setting up Cred Provider NuGet plugin in the agent...\"...\n  echo \"Getting 'installcredprovider.ps1' from 'https://github.com/microsoft/artifacts-credprovider'...\"\n\n  local url=\"https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh\"  \n  \n  echo \"Writing the contents of 'installcredprovider.ps1' locally...\"\n  local installcredproviderPath=\"installcredprovider.sh\"\n  if command -v curl > /dev/null; then\n    curl $url > \"$installcredproviderPath\"\n  else   \n    wget -q -O \"$installcredproviderPath\" \"$url\"\n  fi\n  \n  echo \"Installing plugin...\"\n  . \"$installcredproviderPath\"\n  \n  echo \"Deleting local copy of 'installcredprovider.sh'...\"\n  rm installcredprovider.sh\n\n  if [ ! -d \"$HOME/.nuget/plugins\" ]; then\n    Write-PipelineTelemetryError -category 'Build' 'CredProvider plugin was not installed correctly!'\n    ExitWithExitCode 1  \n  else \n    echo \"CredProvider plugin was installed correctly!\"\n  fi\n\n  # Then, we set the 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS' environment variable to restore from the stable \n  # feeds successfully\n\n  local nugetConfigPath=\"{$repo_root}NuGet.config\"\n\n  if [ ! \"$nugetConfigPath\" ]; then\n    Write-PipelineTelemetryError -category 'Build' \"NuGet.config file not found in repo's root!\"\n    ExitWithExitCode 1  \n  fi\n  \n  local endpoints='['\n  local nugetConfigPackageValues=`cat \"$nugetConfigPath\" | grep \"key=\\\"darc-int-\"`\n  local pattern=\"value=\\\"(.*)\\\"\"\n\n  for value in $nugetConfigPackageValues \n  do\n    if [[ $value =~ $pattern ]]; then\n      local endpoint=\"${BASH_REMATCH[1]}\"  \n      endpoints+=\"{\\\"endpoint\\\": \\\"$endpoint\\\", \\\"password\\\": \\\"$authToken\\\"},\"\n    fi\n  done\n  \n  endpoints=${endpoints%?}\n  endpoints+=']'\n\n  if [ ${#endpoints} -gt 2 ]; then \n      local endpointCredentials=\"{\\\"endpointCredentials\\\": \"$endpoints\"}\"\n\n      echo \"##vso[task.setvariable variable=VSS_NUGET_EXTERNAL_FEED_ENDPOINTS]$endpointCredentials\"\n      echo \"##vso[task.setvariable variable=NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED]False\"\n  else\n    echo \"No internal endpoints found in NuGet.config\"\n  fi\n} \n\n# Workaround for https://github.com/microsoft/msbuild/issues/4430\nfunction InstallDotNetSdkAndRestoreArcade {\n  local dotnetTempDir=\"$repo_root/dotnet\"\n  local dotnetSdkVersion=\"2.1.507\" # After experimentation we know this version works when restoring the SDK (compared to 3.0.*)\n  local restoreProjPath=\"$repo_root/eng/common/restore.proj\"\n  \n  echo \"Installing dotnet SDK version $dotnetSdkVersion to restore Arcade SDK...\"\n  echo \"<Project Sdk=\\\"Microsoft.DotNet.Arcade.Sdk\\\"/>\" > \"$restoreProjPath\"\n  \n  InstallDotNetSdk \"$dotnetTempDir\" \"$dotnetSdkVersion\"\n\n  local res=`$dotnetTempDir/dotnet restore $restoreProjPath`\n  echo \"Arcade SDK restored!\"\n\n  # Cleanup\n  if [ \"$restoreProjPath\" ]; then\n    rm \"$restoreProjPath\"\n  fi\n\n  if [ \"$dotnetTempDir\" ]; then\n    rm -r $dotnetTempDir\n  fi\n}\n\nsource=\"${BASH_SOURCE[0]}\"\noperation=''\nauthToken=''\nrepoName=''\n\nwhile [[ $# > 0 ]]; do\n  opt=\"$(echo \"$1\" | tr \"[:upper:]\" \"[:lower:]\")\"\n  case \"$opt\" in\n    --operation)\n      operation=$2\n      shift\n      ;;\n    --authtoken)\n      authToken=$2\n      shift\n      ;;\n    *)\n      echo \"Invalid argument: $1\"\n      usage\n      exit 1\n      ;;\n  esac\n\n  shift\ndone\n\nwhile [[ -h \"$source\" ]]; do\n  scriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n  source=\"$(readlink \"$source\")\"\n  # if $source was a relative symlink, we need to resolve it relative to the path where the\n  # symlink file was located\n  [[ $source != /* ]] && source=\"$scriptroot/$source\"\ndone\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\n. \"$scriptroot/tools.sh\"\n\nif [ \"$operation\" = \"setup\" ]; then\n  SetupCredProvider $authToken\nelif [ \"$operation\" = \"install-restore\" ]; then\n  InstallDotNetSdkAndRestoreArcade\nelse\n  echo \"Unknown operation '$operation'!\"\nfi\n"
  },
  {
    "path": "eng/common/loc/P22DotNetHtmlLocalization.lss",
    "content": "<?xml version=\"1.0\"?>\n<LS_SETTINGS_FILE>\n  <LS_SETTINGS_DESCRIPTION>\n    <![CDATA[]]>\n  </LS_SETTINGS_DESCRIPTION>\n  <optionSet id=\"LSOptions\">\n    <optionSet id=\"Defaults\" displayName=\"Options Defaults\">\n      <optionSet id=\"Espresso\" displayName=\"Espresso\"/>\n      <optionSet id=\"Parsers\" displayName=\"Parsers\"/>\n    </optionSet>\n    <optionSet id=\"User\" displayName=\"User Overrides\">\n      <optionSet id=\"Espresso\" displayName=\"Espresso\"/>\n      <optionSet id=\"Parsers\" displayName=\"Parsers\"/>\n    </optionSet>\n    <optionSet id=\"Project\" displayName=\"Project Overrides\">\n      <optionSet id=\"Espresso\" displayName=\"Espresso\"/>\n      <optionSet id=\"Parsers\" displayName=\"Parsers\">\n        <optionSet id=\"Parser 22\" displayName=\"POMHTML Parser options\" helpText=\"POMHTML Parser options for Localization Studio.\">\n          <option id=\"SetCharsetInfo\" displayName=\"Set or add Charset information when Generating\" helpText=\"Add Charset information to the Generated file. This is in the format &lt;META HTTP-EQUIV=&quot;Content-Type&quot; CONTENT=&quot;text/html; charset=windows-1252&quot;&gt;. This is based on the Project Target Langauge. If the dir attribute value in the HTML tag i.e. &lt;HTML dir=&quot;ltr&quot;&gt; is not localizable or is missing, its value will be set automatically on Generate if the reading order of the target language is different from the source language.\">\n            <boolean defaultValue=\"1\" currentValue=\"0\"/>\n          </option>\n          <option id=\"IncTermNoResId\" displayName=\"Include Terms which have no Resource Identifier\" helpText=\"Include Terms which have no Resource Identifier. Terms without Resource Identifiers cannot be Updated or Uploaded if they change.\">\n            <boolean defaultValue=\"0\" currentValue=\"1\"/>\n          </option>\n        </optionSet>\n      </optionSet>\n    </optionSet>\n  </optionSet>\n</LS_SETTINGS_FILE>"
  },
  {
    "path": "eng/common/msbuild.ps1",
    "content": "[CmdletBinding(PositionalBinding=$false)]\nParam(\n  [string] $verbosity = 'minimal',\n  [bool] $warnAsError = $true,\n  [bool] $nodeReuse = $true,\n  [switch] $ci,\n  [switch] $prepareMachine,\n  [switch] $excludePrereleaseVS,\n  [string] $msbuildEngine = $null,\n  [Parameter(ValueFromRemainingArguments=$true)][String[]]$extraArgs\n)\n\n. $PSScriptRoot\\tools.ps1\n\ntry {\n  if ($ci) {\n    $nodeReuse = $false\n  }\n\n  MSBuild @extraArgs\n} \ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'Build' -Message $_\n  ExitWithExitCode 1\n}\n\nExitWithExitCode 0"
  },
  {
    "path": "eng/common/msbuild.sh",
    "content": "#!/usr/bin/env bash\n\nsource=\"${BASH_SOURCE[0]}\"\n\n# resolve $source until the file is no longer a symlink\nwhile [[ -h \"$source\" ]]; do\n  scriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n  source=\"$(readlink \"$source\")\"\n  # if $source was a relative symlink, we need to resolve it relative to the path where the\n  # symlink file was located\n  [[ $source != /* ]] && source=\"$scriptroot/$source\"\ndone\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\nverbosity='minimal'\nwarn_as_error=true\nnode_reuse=true\nprepare_machine=false\nextra_args=''\n\nwhile (($# > 0)); do\n  lowerI=\"$(echo $1 | tr \"[:upper:]\" \"[:lower:]\")\"\n  case $lowerI in\n    --verbosity)\n      verbosity=$2\n      shift 2\n      ;;\n    --warnaserror)\n      warn_as_error=$2\n      shift 2\n      ;;\n    --nodereuse)\n      node_reuse=$2\n      shift 2\n      ;;\n    --ci)\n      ci=true\n      shift 1\n      ;;\n    --preparemachine)\n      prepare_machine=true\n      shift 1\n      ;;\n      *)\n      extra_args=\"$extra_args $1\"\n      shift 1\n      ;;\n  esac\ndone\n\n. \"$scriptroot/tools.sh\"\n\nif [[ \"$ci\" == true ]]; then\n  node_reuse=false\nfi\n\nMSBuild $extra_args\nExitWithExitCode 0\n"
  },
  {
    "path": "eng/common/native/CommonLibrary.psm1",
    "content": "<#\n.SYNOPSIS\nHelper module to install an archive to a directory\n\n.DESCRIPTION\nHelper module to download and extract an archive to a specified directory\n\n.PARAMETER Uri\nUri of artifact to download\n\n.PARAMETER InstallDirectory\nDirectory to extract artifact contents to\n\n.PARAMETER Force\nForce download / extraction if file or contents already exist. Default = False\n\n.PARAMETER DownloadRetries\nTotal number of retry attempts. Default = 5\n\n.PARAMETER RetryWaitTimeInSeconds\nWait time between retry attempts in seconds. Default = 30\n\n.NOTES\nReturns False if download or extraction fail, True otherwise\n#>\nfunction DownloadAndExtract {\n  [CmdletBinding(PositionalBinding=$false)]\n  Param (\n    [Parameter(Mandatory=$True)]\n    [string] $Uri,\n    [Parameter(Mandatory=$True)]\n    [string] $InstallDirectory,\n    [switch] $Force = $False,\n    [int] $DownloadRetries = 5,\n    [int] $RetryWaitTimeInSeconds = 30\n  )\n  # Define verbose switch if undefined\n  $Verbose = $VerbosePreference -Eq \"Continue\"\n\n  $TempToolPath = CommonLibrary\\Get-TempPathFilename -Path $Uri\n\n  # Download native tool\n  $DownloadStatus = CommonLibrary\\Get-File -Uri $Uri `\n                                           -Path $TempToolPath `\n                                           -DownloadRetries $DownloadRetries `\n                                           -RetryWaitTimeInSeconds $RetryWaitTimeInSeconds `\n                                           -Force:$Force `\n                                           -Verbose:$Verbose\n\n  if ($DownloadStatus -Eq $False) {\n    Write-Error \"Download failed from $Uri\"\n    return $False\n  }\n\n  # Extract native tool\n  $UnzipStatus = CommonLibrary\\Expand-Zip -ZipPath $TempToolPath `\n                                          -OutputDirectory $InstallDirectory `\n                                          -Force:$Force `\n                                          -Verbose:$Verbose\n\n  if ($UnzipStatus -Eq $False) {\n    # Retry Download one more time with Force=true\n    $DownloadRetryStatus = CommonLibrary\\Get-File -Uri $Uri `\n                                             -Path $TempToolPath `\n                                             -DownloadRetries 1 `\n                                             -RetryWaitTimeInSeconds $RetryWaitTimeInSeconds `\n                                             -Force:$True `\n                                             -Verbose:$Verbose\n\n    if ($DownloadRetryStatus -Eq $False) {\n      Write-Error \"Last attempt of download failed as well\"\n      return $False\n    }\n\n    # Retry unzip again one more time with Force=true\n    $UnzipRetryStatus = CommonLibrary\\Expand-Zip -ZipPath $TempToolPath `\n                                            -OutputDirectory $InstallDirectory `\n                                            -Force:$True `\n                                            -Verbose:$Verbose\n    if ($UnzipRetryStatus -Eq $False)\n    {\n      Write-Error \"Last attempt of unzip failed as well\"\n      # Clean up partial zips and extracts\n      if (Test-Path $TempToolPath) {\n        Remove-Item $TempToolPath -Force\n      }\n      if (Test-Path $InstallDirectory) {\n        Remove-Item $InstallDirectory -Force -Recurse\n      }\n      return $False\n    }\n  }\n\n  return $True\n}\n\n<#\n.SYNOPSIS\nDownload a file, retry on failure\n\n.DESCRIPTION\nDownload specified file and retry if attempt fails\n\n.PARAMETER Uri\nUri of file to download. If Uri is a local path, the file will be copied instead of downloaded\n\n.PARAMETER Path\nPath to download or copy uri file to\n\n.PARAMETER Force\nOverwrite existing file if present. Default = False\n\n.PARAMETER DownloadRetries\nTotal number of retry attempts. Default = 5\n\n.PARAMETER RetryWaitTimeInSeconds\nWait time between retry attempts in seconds Default = 30\n\n#>\nfunction Get-File {\n  [CmdletBinding(PositionalBinding=$false)]\n  Param (\n    [Parameter(Mandatory=$True)]\n    [string] $Uri,\n    [Parameter(Mandatory=$True)]\n    [string] $Path,\n    [int] $DownloadRetries = 5,\n    [int] $RetryWaitTimeInSeconds = 30,\n    [switch] $Force = $False\n  )\n  $Attempt = 0\n\n  if ($Force) {\n    if (Test-Path $Path) {\n      Remove-Item $Path -Force\n    }\n  }\n  if (Test-Path $Path) {\n    Write-Host \"File '$Path' already exists, skipping download\"\n    return $True\n  }\n\n  $DownloadDirectory = Split-Path -ErrorAction Ignore -Path \"$Path\" -Parent\n  if (-Not (Test-Path $DownloadDirectory)) {\n    New-Item -path $DownloadDirectory -force -itemType \"Directory\" | Out-Null\n  }\n\n  $TempPath = \"$Path.tmp\"\n  if (Test-Path -IsValid -Path $Uri) {\n    Write-Verbose \"'$Uri' is a file path, copying temporarily to '$TempPath'\"\n    Copy-Item -Path $Uri -Destination $TempPath\n    Write-Verbose \"Moving temporary file to '$Path'\"\n    Move-Item -Path $TempPath -Destination $Path\n    return $?\n  }\n  else {\n    Write-Verbose \"Downloading $Uri\"\n    # Don't display the console progress UI - it's a huge perf hit\n    $ProgressPreference = 'SilentlyContinue'   \n    while($Attempt -Lt $DownloadRetries)\n    {\n      try {\n        Invoke-WebRequest -UseBasicParsing -Uri $Uri -OutFile $TempPath\n        Write-Verbose \"Downloaded to temporary location '$TempPath'\"\n        Move-Item -Path $TempPath -Destination $Path\n        Write-Verbose \"Moved temporary file to '$Path'\"\n        return $True\n      }\n      catch {\n        $Attempt++\n        if ($Attempt -Lt $DownloadRetries) {\n          $AttemptsLeft = $DownloadRetries - $Attempt\n          Write-Warning \"Download failed, $AttemptsLeft attempts remaining, will retry in $RetryWaitTimeInSeconds seconds\"\n          Start-Sleep -Seconds $RetryWaitTimeInSeconds\n        }\n        else {\n          Write-Error $_\n          Write-Error $_.Exception\n        }\n      }\n    }\n  }\n\n  return $False\n}\n\n<#\n.SYNOPSIS\nGenerate a shim for a native tool\n\n.DESCRIPTION\nCreates a wrapper script (shim) that passes arguments forward to native tool assembly\n\n.PARAMETER ShimName\nThe name of the shim\n\n.PARAMETER ShimDirectory\nThe directory where shims are stored\n\n.PARAMETER ToolFilePath\nPath to file that shim forwards to\n\n.PARAMETER Force\nReplace shim if already present.  Default = False\n\n.NOTES\nReturns $True if generating shim succeeds, $False otherwise\n#>\nfunction New-ScriptShim {\n  [CmdletBinding(PositionalBinding=$false)]\n  Param (\n    [Parameter(Mandatory=$True)]\n    [string] $ShimName,\n    [Parameter(Mandatory=$True)]\n    [string] $ShimDirectory,\n    [Parameter(Mandatory=$True)]\n    [string] $ToolFilePath,\n    [Parameter(Mandatory=$True)]\n    [string] $BaseUri,\n    [switch] $Force\n  )\n  try {\n    Write-Verbose \"Generating '$ShimName' shim\"\n\n    if (-Not (Test-Path $ToolFilePath)){\n      Write-Error \"Specified tool file path '$ToolFilePath' does not exist\"\n      return $False\n    }\n\n    # WinShimmer is a small .NET Framework program that creates .exe shims to bootstrapped programs\n    # Many of the checks for installed programs expect a .exe extension for Windows tools, rather\n    # than a .bat or .cmd file.\n    # Source: https://github.com/dotnet/arcade/tree/master/src/WinShimmer\n    if (-Not (Test-Path \"$ShimDirectory\\WinShimmer\\winshimmer.exe\")) {\n      $InstallStatus = DownloadAndExtract -Uri \"$BaseUri/windows/winshimmer/WinShimmer.zip\" `\n                                          -InstallDirectory $ShimDirectory\\WinShimmer `\n                                          -Force:$Force `\n                                          -DownloadRetries 2 `\n                                          -RetryWaitTimeInSeconds 5 `\n                                          -Verbose:$Verbose\n    }\n\n    if ((Test-Path (Join-Path $ShimDirectory \"$ShimName.exe\"))) {\n      Write-Host \"$ShimName.exe already exists; replacing...\"\n      Remove-Item (Join-Path $ShimDirectory \"$ShimName.exe\")\n    }\n\n    & \"$ShimDirectory\\WinShimmer\\winshimmer.exe\" $ShimName $ToolFilePath $ShimDirectory\n    return $True\n  }\n  catch {\n    Write-Host $_\n    Write-Host $_.Exception\n    return $False\n  }\n}\n\n<#\n.SYNOPSIS\nReturns the machine architecture of the host machine\n\n.NOTES\nReturns 'x64' on 64 bit machines\n Returns 'x86' on 32 bit machines\n#>\nfunction Get-MachineArchitecture {\n  $ProcessorArchitecture = $Env:PROCESSOR_ARCHITECTURE\n  $ProcessorArchitectureW6432 = $Env:PROCESSOR_ARCHITEW6432\n  if($ProcessorArchitecture -Eq \"X86\")\n  {\n    if(($ProcessorArchitectureW6432 -Eq \"\") -Or\n       ($ProcessorArchitectureW6432 -Eq \"X86\")) {\n        return \"x86\"\n    }\n    $ProcessorArchitecture = $ProcessorArchitectureW6432\n  }\n  if (($ProcessorArchitecture -Eq \"AMD64\") -Or\n      ($ProcessorArchitecture -Eq \"IA64\") -Or\n      ($ProcessorArchitecture -Eq \"ARM64\") -Or\n      ($ProcessorArchitecture -Eq \"LOONGARCH64\") -Or\n      ($ProcessorArchitecture -Eq \"RISCV64\")) {\n    return \"x64\"\n  }\n  return \"x86\"\n}\n\n<#\n.SYNOPSIS\nGet the name of a temporary folder under the native install directory\n#>\nfunction Get-TempDirectory {\n  return Join-Path (Get-NativeInstallDirectory) \"temp/\"\n}\n\nfunction Get-TempPathFilename {\n  [CmdletBinding(PositionalBinding=$false)]\n  Param (\n    [Parameter(Mandatory=$True)]\n    [string] $Path\n  )\n  $TempDir = CommonLibrary\\Get-TempDirectory\n  $TempFilename = Split-Path $Path -leaf\n  $TempPath = Join-Path $TempDir $TempFilename\n  return $TempPath\n}\n\n<#\n.SYNOPSIS\nReturns the base directory to use for native tool installation\n\n.NOTES\nReturns the value of the NETCOREENG_INSTALL_DIRECTORY if that environment variable\nis set, or otherwise returns an install directory under the %USERPROFILE%\n#>\nfunction Get-NativeInstallDirectory {\n  $InstallDir = $Env:NETCOREENG_INSTALL_DIRECTORY\n  if (!$InstallDir) {\n    $InstallDir = Join-Path $Env:USERPROFILE \".netcoreeng/native/\"\n  }\n  return $InstallDir\n}\n\n<#\n.SYNOPSIS\nUnzip an archive\n\n.DESCRIPTION\nPowershell module to unzip an archive to a specified directory\n\n.PARAMETER ZipPath (Required)\nPath to archive to unzip\n\n.PARAMETER OutputDirectory (Required)\nOutput directory for archive contents\n\n.PARAMETER Force\nOverwrite output directory contents if they already exist\n\n.NOTES\n- Returns True and does not perform an extraction if output directory already exists but Overwrite is not True.\n- Returns True if unzip operation is successful\n- Returns False if Overwrite is True and it is unable to remove contents of OutputDirectory\n- Returns False if unable to extract zip archive\n#>\nfunction Expand-Zip {\n  [CmdletBinding(PositionalBinding=$false)]\n  Param (\n    [Parameter(Mandatory=$True)]\n    [string] $ZipPath,\n    [Parameter(Mandatory=$True)]\n    [string] $OutputDirectory,\n    [switch] $Force\n  )\n\n  Write-Verbose \"Extracting '$ZipPath' to '$OutputDirectory'\"\n  try {\n    if ((Test-Path $OutputDirectory) -And (-Not $Force)) {\n      Write-Host \"Directory '$OutputDirectory' already exists, skipping extract\"\n      return $True\n    }\n    if (Test-Path $OutputDirectory) {\n      Write-Verbose \"'Force' is 'True', but '$OutputDirectory' exists, removing directory\"\n      Remove-Item $OutputDirectory -Force -Recurse\n      if ($? -Eq $False) {\n        Write-Error \"Unable to remove '$OutputDirectory'\"\n        return $False\n      }\n    }\n\n    $TempOutputDirectory = Join-Path \"$(Split-Path -Parent $OutputDirectory)\" \"$(Split-Path -Leaf $OutputDirectory).tmp\"\n    if (Test-Path $TempOutputDirectory) {\n      Remove-Item $TempOutputDirectory -Force -Recurse\n    }\n    New-Item -Path $TempOutputDirectory -Force -ItemType \"Directory\" | Out-Null\n\n    Add-Type -assembly \"system.io.compression.filesystem\"\n    [io.compression.zipfile]::ExtractToDirectory(\"$ZipPath\", \"$TempOutputDirectory\")\n    if ($? -Eq $False) {\n      Write-Error \"Unable to extract '$ZipPath'\"\n      return $False\n    }\n\n    Move-Item -Path $TempOutputDirectory -Destination $OutputDirectory\n  }\n  catch {\n    Write-Host $_\n    Write-Host $_.Exception\n\n    return $False\n  }\n  return $True\n}\n\nexport-modulemember -function DownloadAndExtract\nexport-modulemember -function Expand-Zip\nexport-modulemember -function Get-File\nexport-modulemember -function Get-MachineArchitecture\nexport-modulemember -function Get-NativeInstallDirectory\nexport-modulemember -function Get-TempDirectory\nexport-modulemember -function Get-TempPathFilename\nexport-modulemember -function New-ScriptShim\n"
  },
  {
    "path": "eng/common/native/common-library.sh",
    "content": "#!/usr/bin/env bash\n\nfunction GetNativeInstallDirectory {\n  local install_dir\n\n  if [[ -z $NETCOREENG_INSTALL_DIRECTORY ]]; then\n    install_dir=$HOME/.netcoreeng/native/\n  else\n    install_dir=$NETCOREENG_INSTALL_DIRECTORY\n  fi\n\n  echo $install_dir\n  return 0\n}\n\nfunction GetTempDirectory {\n\n  echo $(GetNativeInstallDirectory)temp/\n  return 0\n}\n\nfunction ExpandZip {\n  local zip_path=$1\n  local output_directory=$2\n  local force=${3:-false}\n\n  echo \"Extracting $zip_path to $output_directory\"\n  if [[ -d $output_directory ]] && [[ $force = false ]]; then\n    echo \"Directory '$output_directory' already exists, skipping extract\"\n    return 0\n  fi\n\n  if [[ -d $output_directory ]]; then\n    echo \"'Force flag enabled, but '$output_directory' exists. Removing directory\"\n    rm -rf $output_directory\n    if [[ $? != 0 ]]; then\n      Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Unable to remove '$output_directory'\"\n      return 1\n    fi\n  fi\n\n  echo \"Creating directory: '$output_directory'\"\n  mkdir -p $output_directory\n\n  echo \"Extracting archive\"\n  tar -xf $zip_path -C $output_directory\n  if [[ $? != 0 ]]; then\n    Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Unable to extract '$zip_path'\"\n    return 1\n  fi\n\n  return 0\n}\n\nfunction GetCurrentOS {\n  local unameOut=\"$(uname -s)\"\n  case $unameOut in\n    Linux*)     echo \"Linux\";;\n    Darwin*)    echo \"MacOS\";;\n  esac\n  return 0\n}\n\nfunction GetFile {\n  local uri=$1\n  local path=$2\n  local force=${3:-false}\n  local download_retries=${4:-5}\n  local retry_wait_time_seconds=${5:-30}\n\n  if [[ -f $path ]]; then\n    if [[ $force = false ]]; then\n      echo \"File '$path' already exists. Skipping download\"\n      return 0\n    else\n      rm -rf $path\n    fi\n  fi\n\n  if [[ -f $uri ]]; then\n    echo \"'$uri' is a file path, copying file to '$path'\"\n    cp $uri $path\n    return $?\n  fi\n\n  echo \"Downloading $uri\"\n  # Use curl if available, otherwise use wget\n  if command -v curl > /dev/null; then\n    curl \"$uri\" -sSL --retry $download_retries --retry-delay $retry_wait_time_seconds --create-dirs -o \"$path\" --fail\n  else\n    wget -q -O \"$path\" \"$uri\" --tries=\"$download_retries\"\n  fi\n\n  return $?\n}\n\nfunction GetTempPathFileName {\n  local path=$1\n\n  local temp_dir=$(GetTempDirectory)\n  local temp_file_name=$(basename $path)\n  echo $temp_dir$temp_file_name\n  return 0\n}\n\nfunction DownloadAndExtract {\n  local uri=$1\n  local installDir=$2\n  local force=${3:-false}\n  local download_retries=${4:-5}\n  local retry_wait_time_seconds=${5:-30}\n\n  local temp_tool_path=$(GetTempPathFileName $uri)\n\n  echo \"downloading to: $temp_tool_path\"\n\n  # Download file\n  GetFile \"$uri\" \"$temp_tool_path\" $force $download_retries $retry_wait_time_seconds\n  if [[ $? != 0 ]]; then\n    Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Failed to download '$uri' to '$temp_tool_path'.\"\n    return 1\n  fi\n\n  # Extract File\n  echo \"extracting from  $temp_tool_path to $installDir\"\n  ExpandZip \"$temp_tool_path\" \"$installDir\" $force $download_retries $retry_wait_time_seconds\n  if [[ $? != 0 ]]; then\n    Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Failed to extract '$temp_tool_path' to '$installDir'.\"\n    return 1\n  fi\n\n  return 0\n}\n\nfunction NewScriptShim {\n  local shimpath=$1\n  local tool_file_path=$2\n  local force=${3:-false}\n\n  echo \"Generating '$shimpath' shim\"\n  if [[ -f $shimpath ]]; then\n    if [[ $force = false ]]; then\n      echo \"File '$shimpath' already exists.\" >&2\n      return 1\n    else\n      rm -rf $shimpath\n    fi\n  fi\n  \n  if [[ ! -f $tool_file_path ]]; then\n    # try to see if the path is lower cased\n    tool_file_path=\"$(echo $tool_file_path | tr \"[:upper:]\" \"[:lower:]\")\" \n    if [[ ! -f $tool_file_path ]]; then\n      Write-PipelineTelemetryError -category 'NativeToolsBootstrap' \"Specified tool file path:'$tool_file_path' does not exist\"\n      return 1\n    fi\n  fi\n\n  local shim_contents=$'#!/usr/bin/env bash\\n'\n  shim_contents+=\"SHIMARGS=\"$'$1\\n'\n  shim_contents+=\"$tool_file_path\"$' $SHIMARGS\\n'\n\n  # Write shim file\n  echo \"$shim_contents\" > $shimpath\n\n  chmod +x $shimpath\n\n  echo \"Finished generating shim '$shimpath'\"\n\n  return $?\n}\n\n"
  },
  {
    "path": "eng/common/native/init-compiler.sh",
    "content": "#!/bin/sh\n#\n# This file detects the C/C++ compiler and exports it to the CC/CXX environment variables\n#\n# NOTE: some scripts source this file and rely on stdout being empty, make sure\n# to not output *anything* here, unless it is an error message that fails the\n# build.\n\nif [ -z \"$build_arch\" ] || [ -z \"$compiler\" ]; then\n  echo \"Usage...\"\n  echo \"build_arch=<ARCH> compiler=<NAME> init-compiler.sh\"\n  echo \"Specify the target architecture.\"\n  echo \"Specify the name of compiler (clang or gcc).\"\n  exit 1\nfi\n\ncase \"$compiler\" in\n    clang*|-clang*|--clang*)\n        # clangx.y or clang-x.y\n        version=\"$(echo \"$compiler\" | tr -d '[:alpha:]-=')\"\n        majorVersion=\"${version%%.*}\"\n\n        # LLVM based on v18 released in early 2024, with two releases per year\n        maxVersion=\"$((18 + ((($(date +%Y) - 2024) * 12 + $(date +%-m) - 3) / 6)))\"\n        compiler=clang\n        ;;\n\n    gcc*|-gcc*|--gcc*)\n        # gccx.y or gcc-x.y\n        version=\"$(echo \"$compiler\" | tr -d '[:alpha:]-=')\"\n        majorVersion=\"${version%%.*}\"\n\n        # GCC based on v14 released in early 2024, with one release per year\n        maxVersion=\"$((14 + ((($(date +%Y) - 2024) * 12 + $(date +%-m) - 3) / 12)))\"\n        compiler=gcc\n        ;;\nesac\n\ncxxCompiler=\"$compiler++\"\n\n# clear the existing CC and CXX from environment\nCC=\nCXX=\nLDFLAGS=\n\nif [ \"$compiler\" = \"gcc\" ]; then cxxCompiler=\"g++\"; fi\n\ncheck_version_exists() {\n    desired_version=-1\n\n    # Set up the environment to be used for building with the desired compiler.\n    if command -v \"$compiler-$1\" > /dev/null; then\n        desired_version=\"-$1\"\n    elif command -v \"$compiler$1\" > /dev/null; then\n        desired_version=\"$1\"\n    fi\n\n    echo \"$desired_version\"\n}\n\n__baseOS=\"$(uname)\"\nset_compiler_version_from_CC() {\n    if [ \"$__baseOS\" = \"Darwin\" ]; then\n        # On Darwin, the versions from -version/-dumpversion refer to Xcode\n        # versions, not llvm versions, so we can't rely on them.\n        return\n    fi\n\n    version=\"$(\"$CC\" -dumpversion)\"\n    if [ -z \"$version\" ]; then\n        echo \"Error: $CC -dumpversion didn't provide a version\"\n        exit 1\n    fi\n\n    # gcc and clang often display 3 part versions. However, gcc can show only 1 part in some environments.\n    IFS=. read -r majorVersion _ <<EOF\n$version\nEOF\n}\n\nif [ -z \"$CLR_CC\" ]; then\n\n    # Set default versions\n    if [ -z \"$majorVersion\" ]; then\n        minVersion=8\n        maxVersion=\"$((maxVersion + 1))\" # +1 for headspace\n        i=\"$maxVersion\"\n        while [ \"$i\" -ge $minVersion ]; do\n            desired_version=\"$(check_version_exists \"$i\")\"\n            if [ \"$desired_version\" != \"-1\" ]; then majorVersion=\"$i\"; break; fi\n            i=$((i - 1))\n        done\n\n        if [ -z \"$majorVersion\" ]; then\n            if ! command -v \"$compiler\" > /dev/null; then\n                echo \"Error: No compatible version of $compiler was found within the range of $minVersion to $maxVersion. Please upgrade your toolchain or specify the compiler explicitly using CLR_CC and CLR_CXX environment variables.\"\n                exit 1\n            fi\n\n            CC=\"$(command -v \"$compiler\" 2> /dev/null)\"\n            CXX=\"$(command -v \"$cxxCompiler\" 2> /dev/null)\"\n            set_compiler_version_from_CC\n        fi\n    else\n        desired_version=\"$(check_version_exists \"$majorVersion\")\"\n        if [ \"$desired_version\" = \"-1\" ]; then\n            echo \"Error: Could not find specific version of $compiler: $majorVersion.\"\n            exit 1\n        fi\n    fi\n\n    if [ -z \"$CC\" ]; then\n        CC=\"$(command -v \"$compiler$desired_version\" 2> /dev/null)\"\n        CXX=\"$(command -v \"$cxxCompiler$desired_version\" 2> /dev/null)\"\n        if [ -z \"$CXX\" ]; then CXX=\"$(command -v \"$cxxCompiler\" 2> /dev/null)\"; fi\n        set_compiler_version_from_CC\n    fi\nelse\n    if [ ! -f \"$CLR_CC\" ]; then\n        echo \"Error: CLR_CC is set but path '$CLR_CC' does not exist\"\n        exit 1\n    fi\n    CC=\"$CLR_CC\"\n    CXX=\"$CLR_CXX\"\n    set_compiler_version_from_CC\nfi\n\nif [ -z \"$CC\" ]; then\n    echo \"Error: Unable to find $compiler.\"\n    exit 1\nfi\n\nif [ \"$__baseOS\" != \"Darwin\" ]; then\n    # On Darwin, we always want to use the Apple linker.\n\n    # Only lld version >= 9 can be considered stable. lld supports s390x starting from 18.0.\n    if [ \"$compiler\" = \"clang\" ] && [ -n \"$majorVersion\" ] && [ \"$majorVersion\" -ge 9 ] && { [ \"$build_arch\" != \"s390x\" ] || [ \"$majorVersion\" -ge 18 ]; }; then\n        if \"$CC\" -fuse-ld=lld -Wl,--version >/dev/null 2>&1; then\n            LDFLAGS=\"-fuse-ld=lld\"\n        fi\n    fi\nfi\n\nSCAN_BUILD_COMMAND=\"$(command -v \"scan-build$desired_version\" 2> /dev/null)\"\n\nexport CC CXX LDFLAGS SCAN_BUILD_COMMAND\n"
  },
  {
    "path": "eng/common/native/init-distro-rid.sh",
    "content": "#!/bin/sh\n\n# getNonPortableDistroRid\n#\n# Input:\n#   targetOs: (str)\n#   targetArch: (str)\n#   rootfsDir: (str)\n#\n# Return:\n#   non-portable rid\ngetNonPortableDistroRid()\n{\n    targetOs=\"$1\"\n    targetArch=\"$2\"\n    rootfsDir=\"$3\"\n    nonPortableRid=\"\"\n\n    if [ \"$targetOs\" = \"linux\" ]; then\n        # shellcheck disable=SC1091\n        if [ -e \"${rootfsDir}/etc/os-release\" ]; then\n            . \"${rootfsDir}/etc/os-release\"\n            if echo \"${VERSION_ID:-}\" | grep -qE '^([[:digit:]]|\\.)+$'; then\n                nonPortableRid=\"${ID}.${VERSION_ID}-${targetArch}\"\n            else\n                # Rolling release distros either do not set VERSION_ID, set it as blank or\n                # set it to non-version looking string (such as TEMPLATE_VERSION_ID on ArchLinux);\n                # so omit it here to be consistent with everything else.\n                nonPortableRid=\"${ID}-${targetArch}\"\n            fi\n        elif [ -e \"${rootfsDir}/android_platform\" ]; then\n            # shellcheck disable=SC1091\n            . \"${rootfsDir}/android_platform\"\n            nonPortableRid=\"$RID\"\n        fi\n    fi\n\n    if [ \"$targetOs\" = \"freebsd\" ]; then\n        # $rootfsDir can be empty. freebsd-version is a shell script and should always work.\n        __freebsd_major_version=$(\"$rootfsDir\"/bin/freebsd-version | cut -d'.' -f1)\n        nonPortableRid=\"freebsd.$__freebsd_major_version-${targetArch}\"\n    elif command -v getprop >/dev/null && getprop ro.product.system.model | grep -qi android; then\n        __android_sdk_version=$(getprop ro.build.version.sdk)\n        nonPortableRid=\"android.$__android_sdk_version-${targetArch}\"\n    elif [ \"$targetOs\" = \"illumos\" ]; then\n        __uname_version=$(uname -v)\n        nonPortableRid=\"illumos-${targetArch}\"\n    elif [ \"$targetOs\" = \"solaris\" ]; then\n        __uname_version=$(uname -v)\n        __solaris_major_version=$(echo \"$__uname_version\" | cut -d'.' -f1)\n        nonPortableRid=\"solaris.$__solaris_major_version-${targetArch}\"\n    elif [ \"$targetOs\" = \"haiku\" ]; then\n        __uname_release=\"$(uname -r)\"\n        nonPortableRid=haiku.r\"$__uname_release\"-\"$targetArch\"\n    fi\n\n    echo \"$nonPortableRid\" | tr '[:upper:]' '[:lower:]'\n}\n\n# initDistroRidGlobal\n#\n# Input:\n#   os: (str)\n#   arch: (str)\n#   rootfsDir?: (nullable:string)\n#\n# Return:\n#   None\n#\n# Notes:\n#   It is important to note that the function does not return anything, but it\n#   exports the following variables on success:\n#     __DistroRid   : Non-portable rid of the target platform.\n#     __PortableTargetOS  : OS-part of the portable rid that corresponds to the target platform.\ninitDistroRidGlobal()\n{\n    targetOs=\"$1\"\n    targetArch=\"$2\"\n    rootfsDir=\"\"\n    if [ $# -ge 3 ]; then\n        rootfsDir=\"$3\"\n    fi\n\n    if [ -n \"${rootfsDir}\" ]; then\n        # We may have a cross build. Check for the existence of the rootfsDir\n        if [ ! -e \"${rootfsDir}\" ]; then\n            echo \"Error: rootfsDir has been passed, but the location is not valid.\"\n            exit 1\n        fi\n    fi\n\n    __DistroRid=$(getNonPortableDistroRid \"${targetOs}\" \"${targetArch}\" \"${rootfsDir}\")\n\n    if [ -z \"${__PortableTargetOS:-}\" ]; then\n        __PortableTargetOS=\"$targetOs\"\n\n        STRINGS=\"$(command -v strings || true)\"\n        if [ -z \"$STRINGS\" ]; then\n            STRINGS=\"$(command -v llvm-strings || true)\"\n        fi\n\n        # Check for musl-based distros (e.g. Alpine Linux, Void Linux).\n        if \"${rootfsDir}/usr/bin/ldd\" --version 2>&1 | grep -q musl ||\n                ( [ -n \"$STRINGS\" ] && \"$STRINGS\" \"${rootfsDir}/usr/bin/ldd\" 2>&1 | grep -q musl ); then\n            __PortableTargetOS=\"linux-musl\"\n        fi\n    fi\n\n    export __DistroRid __PortableTargetOS\n}\n"
  },
  {
    "path": "eng/common/native/init-os-and-arch.sh",
    "content": "#!/bin/sh\n\n# Use uname to determine what the OS is.\nOSName=$(uname -s | tr '[:upper:]' '[:lower:]')\n\nif command -v getprop && getprop ro.product.system.model 2>&1 | grep -qi android; then\n    OSName=\"android\"\nfi\n\ncase \"$OSName\" in\nfreebsd|linux|netbsd|openbsd|sunos|android|haiku)\n    os=\"$OSName\" ;;\ndarwin)\n    os=osx ;;\n*)\n    echo \"Unsupported OS $OSName detected!\"\n    exit 1 ;;\nesac\n\n# On Solaris, `uname -m` is discouraged, see https://docs.oracle.com/cd/E36784_01/html/E36870/uname-1.html\n# and `uname -p` returns processor type (e.g. i386 on amd64).\n# The appropriate tool to determine CPU is isainfo(1) https://docs.oracle.com/cd/E36784_01/html/E36870/isainfo-1.html.\nif [ \"$os\" = \"sunos\" ]; then\n    if uname -o 2>&1 | grep -q illumos; then\n        os=\"illumos\"\n    else\n        os=\"solaris\"\n    fi\n    CPUName=$(isainfo -n)\nelse\n    # For the rest of the operating systems, use uname(1) to determine what the CPU is.\n    CPUName=$(uname -m)\nfi\n\ncase \"$CPUName\" in\n    arm64|aarch64)\n        arch=arm64\n        if [ \"$(getconf LONG_BIT)\" -lt 64 ]; then\n            # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)\n            arch=arm\n        fi\n        ;;\n\n    loongarch64)\n        arch=loongarch64\n        ;;\n\n    riscv64)\n        arch=riscv64\n        ;;\n\n    amd64|x86_64)\n        arch=x64\n        ;;\n\n    armv7l|armv8l)\n        # shellcheck disable=SC1091\n        if (NAME=\"\"; . /etc/os-release; test \"$NAME\" = \"Tizen\"); then\n            arch=armel\n        else\n            arch=arm\n        fi\n        ;;\n\n    armv6l)\n        arch=armv6\n        ;;\n\n    i[3-6]86)\n        echo \"Unsupported CPU $CPUName detected, build might not succeed!\"\n        arch=x86\n        ;;\n\n    s390x)\n        arch=s390x\n        ;;\n\n    ppc64le)\n        arch=ppc64le\n        ;;\n    *)\n        echo \"Unknown CPU $CPUName detected!\"\n        exit 1\n        ;;\nesac\n"
  },
  {
    "path": "eng/common/native/install-cmake-test.sh",
    "content": "#!/usr/bin/env bash\n\nsource=\"${BASH_SOURCE[0]}\"\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\n. $scriptroot/common-library.sh\n\nbase_uri=\ninstall_path=\nversion=\nclean=false\nforce=false\ndownload_retries=5\nretry_wait_time_seconds=30\n\nwhile (($# > 0)); do\n  lowerI=\"$(echo $1 | tr \"[:upper:]\" \"[:lower:]\")\"\n  case $lowerI in\n    --baseuri)\n      base_uri=$2\n      shift 2\n      ;;\n    --installpath)\n      install_path=$2\n      shift 2\n      ;;\n    --version)\n      version=$2\n      shift 2\n      ;;\n    --clean)\n      clean=true\n      shift 1\n      ;;\n    --force)\n      force=true\n      shift 1\n      ;;\n    --downloadretries)\n      download_retries=$2\n      shift 2\n      ;;\n    --retrywaittimeseconds)\n      retry_wait_time_seconds=$2\n      shift 2\n      ;;\n    --help)\n      echo \"Common settings:\"\n      echo \"  --baseuri <value>        Base file directory or Url wrom which to acquire tool archives\"\n      echo \"  --installpath <value>    Base directory to install native tool to\"\n      echo \"  --clean                  Don't install the tool, just clean up the current install of the tool\"\n      echo \"  --force                  Force install of tools even if they previously exist\"\n      echo \"  --help                   Print help and exit\"\n      echo \"\"\n      echo \"Advanced settings:\"\n      echo \"  --downloadretries        Total number of retry attempts\"\n      echo \"  --retrywaittimeseconds   Wait time between retry attempts in seconds\"\n      echo \"\"\n      exit 0\n      ;;\n  esac\ndone\n\ntool_name=\"cmake-test\"\ntool_os=$(GetCurrentOS)\ntool_folder=\"$(echo $tool_os | tr \"[:upper:]\" \"[:lower:]\")\"\ntool_arch=\"x86_64\"\ntool_name_moniker=\"$tool_name-$version-$tool_os-$tool_arch\"\ntool_install_directory=\"$install_path/$tool_name/$version\"\ntool_file_path=\"$tool_install_directory/$tool_name_moniker/bin/$tool_name\"\nshim_path=\"$install_path/$tool_name.sh\"\nuri=\"${base_uri}/$tool_folder/$tool_name/$tool_name_moniker.tar.gz\"\n\n# Clean up tool and installers\nif [[ $clean = true ]]; then\n  echo \"Cleaning $tool_install_directory\"\n  if [[ -d $tool_install_directory ]]; then\n    rm -rf $tool_install_directory\n  fi\n\n  echo \"Cleaning $shim_path\"\n  if [[ -f $shim_path ]]; then\n    rm -rf $shim_path\n  fi\n\n  tool_temp_path=$(GetTempPathFileName $uri)\n  echo \"Cleaning $tool_temp_path\"\n  if [[ -f $tool_temp_path ]]; then\n    rm -rf $tool_temp_path\n  fi\n\n  exit 0\nfi\n\n# Install tool\nif [[ -f $tool_file_path ]] && [[ $force = false ]]; then\n  echo \"$tool_name ($version) already exists, skipping install\"\n  exit 0\nfi\n\nDownloadAndExtract $uri $tool_install_directory $force $download_retries $retry_wait_time_seconds\n\nif [[ $? != 0 ]]; then\n  Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Installation failed'\n  exit 1\nfi\n\n# Generate Shim\n# Always rewrite shims so that we are referencing the expected version\nNewScriptShim $shim_path $tool_file_path true\n\nif [[ $? != 0 ]]; then\n  Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Shim generation failed'\n  exit 1\nfi\n\nexit 0\n"
  },
  {
    "path": "eng/common/native/install-cmake.sh",
    "content": "#!/usr/bin/env bash\n\nsource=\"${BASH_SOURCE[0]}\"\nscriptroot=\"$( cd -P \"$( dirname \"$source\" )\" && pwd )\"\n\n. $scriptroot/common-library.sh\n\nbase_uri=\ninstall_path=\nversion=\nclean=false\nforce=false\ndownload_retries=5\nretry_wait_time_seconds=30\n\nwhile (($# > 0)); do\n  lowerI=\"$(echo $1 | tr \"[:upper:]\" \"[:lower:]\")\"\n  case $lowerI in\n    --baseuri)\n      base_uri=$2\n      shift 2\n      ;;\n    --installpath)\n      install_path=$2\n      shift 2\n      ;;\n    --version)\n      version=$2\n      shift 2\n      ;;\n    --clean)\n      clean=true\n      shift 1\n      ;;\n    --force)\n      force=true\n      shift 1\n      ;;\n    --downloadretries)\n      download_retries=$2\n      shift 2\n      ;;\n    --retrywaittimeseconds)\n      retry_wait_time_seconds=$2\n      shift 2\n      ;;\n    --help)\n      echo \"Common settings:\"\n      echo \"  --baseuri <value>        Base file directory or Url wrom which to acquire tool archives\"\n      echo \"  --installpath <value>    Base directory to install native tool to\"\n      echo \"  --clean                  Don't install the tool, just clean up the current install of the tool\"\n      echo \"  --force                  Force install of tools even if they previously exist\"\n      echo \"  --help                   Print help and exit\"\n      echo \"\"\n      echo \"Advanced settings:\"\n      echo \"  --downloadretries        Total number of retry attempts\"\n      echo \"  --retrywaittimeseconds   Wait time between retry attempts in seconds\"\n      echo \"\"\n      exit 0\n      ;;\n  esac\ndone\n\ntool_name=\"cmake\"\ntool_os=$(GetCurrentOS)\ntool_folder=\"$(echo $tool_os | tr \"[:upper:]\" \"[:lower:]\")\"\ntool_arch=\"x86_64\"\ntool_name_moniker=\"$tool_name-$version-$tool_os-$tool_arch\"\ntool_install_directory=\"$install_path/$tool_name/$version\"\ntool_file_path=\"$tool_install_directory/$tool_name_moniker/bin/$tool_name\"\nshim_path=\"$install_path/$tool_name.sh\"\nuri=\"${base_uri}/$tool_folder/$tool_name/$tool_name_moniker.tar.gz\"\n\n# Clean up tool and installers\nif [[ $clean = true ]]; then\n  echo \"Cleaning $tool_install_directory\"\n  if [[ -d $tool_install_directory ]]; then\n    rm -rf $tool_install_directory\n  fi\n\n  echo \"Cleaning $shim_path\"\n  if [[ -f $shim_path ]]; then\n    rm -rf $shim_path\n  fi\n\n  tool_temp_path=$(GetTempPathFileName $uri)\n  echo \"Cleaning $tool_temp_path\"\n  if [[ -f $tool_temp_path ]]; then\n    rm -rf $tool_temp_path\n  fi\n\n  exit 0\nfi\n\n# Install tool\nif [[ -f $tool_file_path ]] && [[ $force = false ]]; then\n  echo \"$tool_name ($version) already exists, skipping install\"\n  exit 0\nfi\n\nDownloadAndExtract $uri $tool_install_directory $force $download_retries $retry_wait_time_seconds\n\nif [[ $? != 0 ]]; then\n  Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Installation failed'\n  exit 1\nfi\n\n# Generate Shim\n# Always rewrite shims so that we are referencing the expected version\nNewScriptShim $shim_path $tool_file_path true\n\nif [[ $? != 0 ]]; then\n  Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Shim generation failed'\n  exit 1\nfi\n\nexit 0\n"
  },
  {
    "path": "eng/common/native/install-dependencies.sh",
    "content": "#!/bin/sh\n\nset -e\n\n# This is a simple script primarily used for CI to install necessary dependencies\n#\n# Usage:\n#\n# ./install-dependencies.sh <OS>\n\nos=\"$(echo \"$1\" | tr \"[:upper:]\" \"[:lower:]\")\"\n\nif [ -z \"$os\" ]; then\n    . \"$(dirname \"$0\")\"/init-os-and-arch.sh\nfi\n\ncase \"$os\" in\n    linux)\n        if [ -e /etc/os-release ]; then\n            . /etc/os-release\n        fi\n\n        if [ \"$ID\" = \"debian\" ] || [ \"$ID_LIKE\" = \"debian\" ]; then\n            apt update\n\n            apt install -y build-essential gettext locales cmake llvm clang lld lldb liblldb-dev libunwind8-dev libicu-dev liblttng-ust-dev \\\n                libssl-dev libkrb5-dev zlib1g-dev pigz cpio\n\n            localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8\n        elif [ \"$ID\" = \"fedora\" ] || [ \"$ID\" = \"rhel\" ]; then\n            dnf install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel zlib-devel lttng-ust-devel pigz cpio\n        elif [ \"$ID\" = \"alpine\" ]; then\n            apk add build-base cmake bash curl clang llvm-dev lld lldb krb5-dev lttng-ust-dev icu-dev zlib-dev openssl-dev pigz cpio\n        else\n            echo \"Unsupported distro. distro: $ID\"\n            exit 1\n        fi\n        ;;\n\n    osx|maccatalyst|ios|iossimulator|tvos|tvossimulator)\n        echo \"Installed xcode version: $(xcode-select -p)\"\n\n        export HOMEBREW_NO_INSTALL_CLEANUP=1\n        export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1\n        # Skip brew update for now, see https://github.com/actions/setup-python/issues/577\n        # brew update --preinstall\n        brew bundle --no-upgrade --no-lock --file=- <<EOF\nbrew \"cmake\"\nbrew \"icu4c\"\nbrew \"openssl@3\"\nbrew \"pkgconf\"\nbrew \"python3\"\nbrew \"pigz\"\nEOF\n        ;;\n\n    *)\n        echo \"Unsupported platform. OS: $os\"\n        exit 1\n        ;;\nesac\n"
  },
  {
    "path": "eng/common/native/install-tool.ps1",
    "content": "<#\n.SYNOPSIS\nInstall native tool\n\n.DESCRIPTION\nInstall cmake native tool from Azure blob storage\n\n.PARAMETER InstallPath\nBase directory to install native tool to\n\n.PARAMETER BaseUri\nBase file directory or Url from which to acquire tool archives\n\n.PARAMETER CommonLibraryDirectory\nPath to folder containing common library modules\n\n.PARAMETER Force\nForce install of tools even if they previously exist\n\n.PARAMETER Clean\nDon't install the tool, just clean up the current install of the tool\n\n.PARAMETER DownloadRetries\nTotal number of retry attempts\n\n.PARAMETER RetryWaitTimeInSeconds\nWait time between retry attempts in seconds\n\n.NOTES\nReturns 0 if install succeeds, 1 otherwise\n#>\n[CmdletBinding(PositionalBinding=$false)]\nParam (\n  [Parameter(Mandatory=$True)]\n  [string] $ToolName,\n  [Parameter(Mandatory=$True)]\n  [string] $InstallPath,\n  [Parameter(Mandatory=$True)]\n  [string] $BaseUri,\n  [Parameter(Mandatory=$True)]\n  [string] $Version,\n  [string] $CommonLibraryDirectory = $PSScriptRoot,\n  [switch] $Force = $False,\n  [switch] $Clean = $False,\n  [int] $DownloadRetries = 5,\n  [int] $RetryWaitTimeInSeconds = 30\n)\n\n. $PSScriptRoot\\..\\pipeline-logging-functions.ps1\n\n# Import common library modules\nImport-Module -Name (Join-Path $CommonLibraryDirectory \"CommonLibrary.psm1\")\n\ntry {\n  # Define verbose switch if undefined\n  $Verbose = $VerbosePreference -Eq \"Continue\"\n\n  $Arch = CommonLibrary\\Get-MachineArchitecture\n  $ToolOs = \"win64\"\n  if($Arch -Eq \"x32\") {\n    $ToolOs = \"win32\"\n  }\n  $ToolNameMoniker = \"$ToolName-$Version-$ToolOs-$Arch\"\n  $ToolInstallDirectory = Join-Path $InstallPath \"$ToolName\\$Version\\\"\n  $Uri = \"$BaseUri/windows/$ToolName/$ToolNameMoniker.zip\"\n  $ShimPath = Join-Path $InstallPath \"$ToolName.exe\"\n\n  if ($Clean) {\n    Write-Host \"Cleaning $ToolInstallDirectory\"\n    if (Test-Path $ToolInstallDirectory) {\n      Remove-Item $ToolInstallDirectory -Force -Recurse\n    }\n    Write-Host \"Cleaning $ShimPath\"\n    if (Test-Path $ShimPath) {\n      Remove-Item $ShimPath -Force\n    }\n    $ToolTempPath = CommonLibrary\\Get-TempPathFilename -Path $Uri\n    Write-Host \"Cleaning $ToolTempPath\"\n    if (Test-Path $ToolTempPath) {\n      Remove-Item $ToolTempPath -Force\n    }\n    exit 0\n  }\n\n  # Install tool\n  if ((Test-Path $ToolInstallDirectory) -And (-Not $Force)) {\n    Write-Verbose \"$ToolName ($Version) already exists, skipping install\"\n  }\n  else {\n    $InstallStatus = CommonLibrary\\DownloadAndExtract -Uri $Uri `\n                                                      -InstallDirectory $ToolInstallDirectory `\n                                                      -Force:$Force `\n                                                      -DownloadRetries $DownloadRetries `\n                                                      -RetryWaitTimeInSeconds $RetryWaitTimeInSeconds `\n                                                      -Verbose:$Verbose\n\n    if ($InstallStatus -Eq $False) {\n      Write-PipelineTelemetryError \"Installation failed\" -Category \"NativeToolsetBootstrapping\"\n      exit 1\n    }\n  }\n\n  $ToolFilePath = Get-ChildItem $ToolInstallDirectory -Recurse -Filter \"$ToolName.exe\" | % { $_.FullName }\n  if (@($ToolFilePath).Length -Gt 1) {\n    Write-Error \"There are multiple copies of $ToolName in $($ToolInstallDirectory): `n$(@($ToolFilePath | out-string))\"\n    exit 1\n  } elseif (@($ToolFilePath).Length -Lt 1) {\n    Write-Host \"$ToolName was not found in $ToolInstallDirectory.\"\n    exit 1\n  }\n\n  # Generate shim\n  # Always rewrite shims so that we are referencing the expected version\n  $GenerateShimStatus = CommonLibrary\\New-ScriptShim -ShimName $ToolName `\n                                                     -ShimDirectory $InstallPath `\n                                                     -ToolFilePath \"$ToolFilePath\" `\n                                                     -BaseUri $BaseUri `\n                                                     -Force:$Force `\n                                                     -Verbose:$Verbose\n\n  if ($GenerateShimStatus -Eq $False) {\n    Write-PipelineTelemetryError \"Generate shim failed\" -Category \"NativeToolsetBootstrapping\"\n    return 1\n  }\n\n  exit 0\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category \"NativeToolsetBootstrapping\" -Message $_\n  exit 1\n}\n"
  },
  {
    "path": "eng/common/pipeline-logging-functions.ps1",
    "content": "# Source for this file was taken from https://github.com/microsoft/azure-pipelines-task-lib/blob/11c9439d4af17e6475d9fe058e6b2e03914d17e6/powershell/VstsTaskSdk/LoggingCommandFunctions.ps1 and modified.\n\n# NOTE: You should not be calling these method directly as they are likely to change.  Instead you should be calling the Write-Pipeline* functions defined in tools.ps1\n\n$script:loggingCommandPrefix = '##vso['\n$script:loggingCommandEscapeMappings = @( # TODO: WHAT ABOUT \"=\"? WHAT ABOUT \"%\"?\n    New-Object psobject -Property @{ Token = ';' ; Replacement = '%3B' }\n    New-Object psobject -Property @{ Token = \"`r\" ; Replacement = '%0D' }\n    New-Object psobject -Property @{ Token = \"`n\" ; Replacement = '%0A' }\n    New-Object psobject -Property @{ Token = \"]\" ; Replacement = '%5D' }\n)\n# TODO: BUG: Escape % ???\n# TODO: Add test to verify don't need to escape \"=\".\n\n# Specify \"-Force\" to force pipeline formatted output even if \"$ci\" is false or not set\nfunction Write-PipelineTelemetryError {\n    [CmdletBinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [string]$Category,\n        [Parameter(Mandatory = $true)]\n        [string]$Message,\n        [Parameter(Mandatory = $false)]\n        [string]$Type = 'error',\n        [string]$ErrCode,\n        [string]$SourcePath,\n        [string]$LineNumber,\n        [string]$ColumnNumber,\n        [switch]$AsOutput,\n        [switch]$Force)\n\n    $PSBoundParameters.Remove('Category') | Out-Null\n\n    if ($Force -Or ((Test-Path variable:ci) -And $ci)) {\n        $Message = \"(NETCORE_ENGINEERING_TELEMETRY=$Category) $Message\"\n    }\n    $PSBoundParameters.Remove('Message') | Out-Null\n    $PSBoundParameters.Add('Message', $Message)\n    Write-PipelineTaskError @PSBoundParameters\n}\n\n# Specify \"-Force\" to force pipeline formatted output even if \"$ci\" is false or not set\nfunction Write-PipelineTaskError {\n    [CmdletBinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [string]$Message,\n        [Parameter(Mandatory = $false)]\n        [string]$Type = 'error',\n        [string]$ErrCode,\n        [string]$SourcePath,\n        [string]$LineNumber,\n        [string]$ColumnNumber,\n        [switch]$AsOutput,\n        [switch]$Force\n    )\n\n    if (!$Force -And (-Not (Test-Path variable:ci) -Or !$ci)) {\n        if ($Type -eq 'error') {\n            Write-Host $Message -ForegroundColor Red\n            return\n        }\n        elseif ($Type -eq 'warning') {\n            Write-Host $Message -ForegroundColor Yellow\n            return\n        }\n    }\n\n    if (($Type -ne 'error') -and ($Type -ne 'warning')) {\n        Write-Host $Message\n        return\n    }\n    $PSBoundParameters.Remove('Force') | Out-Null      \n    if (-not $PSBoundParameters.ContainsKey('Type')) {\n        $PSBoundParameters.Add('Type', 'error')\n    }\n    Write-LogIssue @PSBoundParameters\n}\n  \nfunction Write-PipelineSetVariable {\n    [CmdletBinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [string]$Name,\n        [string]$Value,\n        [switch]$Secret,\n        [switch]$AsOutput,\n        [bool]$IsMultiJobVariable = $true)\n\n    if ((Test-Path variable:ci) -And $ci) {\n        Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data $Value -Properties @{\n            'variable' = $Name\n            'isSecret' = $Secret\n            'isOutput' = $IsMultiJobVariable\n        } -AsOutput:$AsOutput\n    }\n}\n  \nfunction Write-PipelinePrependPath {\n    [CmdletBinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [string]$Path,\n        [switch]$AsOutput)\n\n    if ((Test-Path variable:ci) -And $ci) {\n        Write-LoggingCommand -Area 'task' -Event 'prependpath' -Data $Path -AsOutput:$AsOutput\n    }\n}\n\nfunction Write-PipelineSetResult {\n    [CmdletBinding()]\n    param(\n        [ValidateSet(\"Succeeded\", \"SucceededWithIssues\", \"Failed\", \"Cancelled\", \"Skipped\")]\n        [Parameter(Mandatory = $true)]\n        [string]$Result,\n        [string]$Message)\n    if ((Test-Path variable:ci) -And $ci) {\n        Write-LoggingCommand -Area 'task' -Event 'complete' -Data $Message -Properties @{\n            'result' = $Result\n        }\n    }\n}\n\n<########################################\n# Private functions.\n########################################>\nfunction Format-LoggingCommandData {\n    [CmdletBinding()]\n    param([string]$Value, [switch]$Reverse)\n\n    if (!$Value) {\n        return ''\n    }\n\n    if (!$Reverse) {\n        foreach ($mapping in $script:loggingCommandEscapeMappings) {\n            $Value = $Value.Replace($mapping.Token, $mapping.Replacement)\n        }\n    }\n    else {\n        for ($i = $script:loggingCommandEscapeMappings.Length - 1 ; $i -ge 0 ; $i--) {\n            $mapping = $script:loggingCommandEscapeMappings[$i]\n            $Value = $Value.Replace($mapping.Replacement, $mapping.Token)\n        }\n    }\n\n    return $Value\n}\n\nfunction Format-LoggingCommand {\n    [CmdletBinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [string]$Area,\n        [Parameter(Mandatory = $true)]\n        [string]$Event,\n        [string]$Data,\n        [hashtable]$Properties)\n\n    # Append the preamble.\n    [System.Text.StringBuilder]$sb = New-Object -TypeName System.Text.StringBuilder\n    $null = $sb.Append($script:loggingCommandPrefix).Append($Area).Append('.').Append($Event)\n\n    # Append the properties.\n    if ($Properties) {\n        $first = $true\n        foreach ($key in $Properties.Keys) {\n            [string]$value = Format-LoggingCommandData $Properties[$key]\n            if ($value) {\n                if ($first) {\n                    $null = $sb.Append(' ')\n                    $first = $false\n                }\n                else {\n                    $null = $sb.Append(';')\n                }\n\n                $null = $sb.Append(\"$key=$value\")\n            }\n        }\n    }\n\n    # Append the tail and output the value.\n    $Data = Format-LoggingCommandData $Data\n    $sb.Append(']').Append($Data).ToString()\n}\n\nfunction Write-LoggingCommand {\n    [CmdletBinding(DefaultParameterSetName = 'Parameters')]\n    param(\n        [Parameter(Mandatory = $true, ParameterSetName = 'Parameters')]\n        [string]$Area,\n        [Parameter(Mandatory = $true, ParameterSetName = 'Parameters')]\n        [string]$Event,\n        [Parameter(ParameterSetName = 'Parameters')]\n        [string]$Data,\n        [Parameter(ParameterSetName = 'Parameters')]\n        [hashtable]$Properties,\n        [Parameter(Mandatory = $true, ParameterSetName = 'Object')]\n        $Command,\n        [switch]$AsOutput)\n\n    if ($PSCmdlet.ParameterSetName -eq 'Object') {\n        Write-LoggingCommand -Area $Command.Area -Event $Command.Event -Data $Command.Data -Properties $Command.Properties -AsOutput:$AsOutput\n        return\n    }\n\n    $command = Format-LoggingCommand -Area $Area -Event $Event -Data $Data -Properties $Properties\n    if ($AsOutput) {\n        $command\n    }\n    else {\n        Write-Host $command\n    }\n}\n\nfunction Write-LogIssue {\n    [CmdletBinding()]\n    param(\n        [ValidateSet('warning', 'error')]\n        [Parameter(Mandatory = $true)]\n        [string]$Type,\n        [string]$Message,\n        [string]$ErrCode,\n        [string]$SourcePath,\n        [string]$LineNumber,\n        [string]$ColumnNumber,\n        [switch]$AsOutput)\n\n    $command = Format-LoggingCommand -Area 'task' -Event 'logissue' -Data $Message -Properties @{\n        'type'         = $Type\n        'code'         = $ErrCode\n        'sourcepath'   = $SourcePath\n        'linenumber'   = $LineNumber\n        'columnnumber' = $ColumnNumber\n    }\n    if ($AsOutput) {\n        return $command\n    }\n\n    if ($Type -eq 'error') {\n        $foregroundColor = $host.PrivateData.ErrorForegroundColor\n        $backgroundColor = $host.PrivateData.ErrorBackgroundColor\n        if ($foregroundColor -isnot [System.ConsoleColor] -or $backgroundColor -isnot [System.ConsoleColor]) {\n            $foregroundColor = [System.ConsoleColor]::Red\n            $backgroundColor = [System.ConsoleColor]::Black\n        }\n    }\n    else {\n        $foregroundColor = $host.PrivateData.WarningForegroundColor\n        $backgroundColor = $host.PrivateData.WarningBackgroundColor\n        if ($foregroundColor -isnot [System.ConsoleColor] -or $backgroundColor -isnot [System.ConsoleColor]) {\n            $foregroundColor = [System.ConsoleColor]::Yellow\n            $backgroundColor = [System.ConsoleColor]::Black\n        }\n    }\n\n    Write-Host $command -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor\n}\n"
  },
  {
    "path": "eng/common/pipeline-logging-functions.sh",
    "content": "#!/usr/bin/env bash\n\nfunction Write-PipelineTelemetryError {\n  local telemetry_category=''\n  local force=false\n  local function_args=()\n  local message=''\n  while [[ $# -gt 0 ]]; do\n    opt=\"$(echo \"${1/#--/-}\" | tr \"[:upper:]\" \"[:lower:]\")\"\n    case \"$opt\" in\n      -category|-c)\n        telemetry_category=$2\n        shift\n        ;;\n      -force|-f)\n        force=true\n        ;;\n      -*)\n        function_args+=(\"$1 $2\")\n        shift\n        ;;\n      *)\n        message=$*\n        ;;\n    esac\n    shift\n  done\n\n  if [[ $force != true ]] && [[ \"$ci\" != true ]]; then\n    echo \"$message\" >&2\n    return\n  fi\n\n  if [[ $force == true ]]; then\n    function_args+=(\"-force\")\n  fi\n  message=\"(NETCORE_ENGINEERING_TELEMETRY=$telemetry_category) $message\"\n  function_args+=(\"$message\")\n  Write-PipelineTaskError ${function_args[@]}\n}\n\nfunction Write-PipelineTaskError {\n  local message_type=\"error\"\n  local sourcepath=''\n  local linenumber=''\n  local columnnumber=''\n  local error_code=''\n  local force=false\n\n  while [[ $# -gt 0 ]]; do\n    opt=\"$(echo \"${1/#--/-}\" | tr \"[:upper:]\" \"[:lower:]\")\"\n    case \"$opt\" in\n      -type|-t)\n        message_type=$2\n        shift\n        ;;\n      -sourcepath|-s)\n        sourcepath=$2\n        shift\n        ;;\n      -linenumber|-ln)\n        linenumber=$2\n        shift\n        ;;\n      -columnnumber|-cn)\n        columnnumber=$2\n        shift\n        ;;\n      -errcode|-e)\n        error_code=$2\n        shift\n        ;;\n      -force|-f)\n        force=true\n        ;;\n      *)\n        break\n        ;;\n    esac\n\n    shift\n  done\n\n  if [[ $force != true ]] && [[ \"$ci\" != true ]]; then\n    echo \"$@\" >&2\n    return\n  fi\n\n  local message=\"##vso[task.logissue\"\n\n  message=\"$message type=$message_type\"\n\n  if [ -n \"$sourcepath\" ]; then\n    message=\"$message;sourcepath=$sourcepath\"\n  fi\n\n  if [ -n \"$linenumber\" ]; then\n    message=\"$message;linenumber=$linenumber\"\n  fi\n\n  if [ -n \"$columnnumber\" ]; then\n    message=\"$message;columnnumber=$columnnumber\"\n  fi\n\n  if [ -n \"$error_code\" ]; then\n    message=\"$message;code=$error_code\"\n  fi\n\n  message=\"$message]$*\"\n  echo \"$message\"\n}\n\nfunction Write-PipelineSetVariable {\n  if [[ \"$ci\" != true ]]; then\n    return\n  fi\n\n  local name=''\n  local value=''\n  local secret=false\n  local as_output=false\n  local is_multi_job_variable=true\n\n  while [[ $# -gt 0 ]]; do\n    opt=\"$(echo \"${1/#--/-}\" | tr \"[:upper:]\" \"[:lower:]\")\"\n    case \"$opt\" in\n      -name|-n)\n        name=$2\n        shift\n        ;;\n      -value|-v)\n        value=$2\n        shift\n        ;;\n      -secret|-s)\n        secret=true\n        ;;\n      -as_output|-a)\n        as_output=true\n        ;;\n      -is_multi_job_variable|-i)\n        is_multi_job_variable=$2\n        shift\n        ;;\n    esac\n    shift\n  done\n\n  value=${value/;/%3B}\n  value=${value/\\\\r/%0D}\n  value=${value/\\\\n/%0A}\n  value=${value/]/%5D}\n\n  local message=\"##vso[task.setvariable variable=$name;isSecret=$secret;isOutput=$is_multi_job_variable]$value\"\n\n  if [[ \"$as_output\" == true ]]; then\n    $message\n  else\n    echo \"$message\"\n  fi\n}\n\nfunction Write-PipelinePrependPath {\n  local prepend_path=''\n\n  while [[ $# -gt 0 ]]; do\n    opt=\"$(echo \"${1/#--/-}\" | tr \"[:upper:]\" \"[:lower:]\")\"\n    case \"$opt\" in\n      -path|-p)\n        prepend_path=$2\n        shift\n        ;;\n    esac\n    shift\n  done\n\n  export PATH=\"$prepend_path:$PATH\"\n\n  if [[ \"$ci\" == true ]]; then\n    echo \"##vso[task.prependpath]$prepend_path\"\n  fi\n}\n\nfunction Write-PipelineSetResult {\n  local result=''\n  local message=''\n\n  while [[ $# -gt 0 ]]; do\n    opt=\"$(echo \"${1/#--/-}\" | tr \"[:upper:]\" \"[:lower:]\")\"\n    case \"$opt\" in\n      -result|-r)\n        result=$2\n        shift\n        ;;\n      -message|-m)\n        message=$2\n        shift\n        ;;\n    esac\n    shift\n  done\n\n  if [[ \"$ci\" == true ]]; then\n    echo \"##vso[task.complete result=$result;]$message\"\n  fi\n}\n"
  },
  {
    "path": "eng/common/post-build/check-channel-consistency.ps1",
    "content": "param(\n  [Parameter(Mandatory=$true)][string] $PromoteToChannels,            # List of channels that the build should be promoted to\n  [Parameter(Mandatory=$true)][array] $AvailableChannelIds            # List of channel IDs available in the YAML implementation\n)\n\ntry {\n  $ErrorActionPreference = 'Stop'\n  Set-StrictMode -Version 2.0\n\n  # `tools.ps1` checks $ci to perform some actions. Since the post-build\n  # scripts don't necessarily execute in the same agent that run the\n  # build.ps1/sh script this variable isn't automatically set.\n  $ci = $true\n  $disableConfigureToolsetImport = $true\n  . $PSScriptRoot\\..\\tools.ps1\n\n  if ($PromoteToChannels -eq \"\") {\n    Write-PipelineTaskError -Type 'warning' -Message \"This build won't publish assets as it's not configured to any Maestro channel. If that wasn't intended use Darc to configure a default channel using add-default-channel for this branch or to promote it to a channel using add-build-to-channel. See https://github.com/dotnet/arcade/blob/main/Documentation/Darc.md#assigning-an-individual-build-to-a-channel for more info.\"\n    ExitWithExitCode 0\n  }\n\n  # Check that every channel that Maestro told to promote the build to \n  # is available in YAML\n  $PromoteToChannelsIds = $PromoteToChannels -split \"\\D\" | Where-Object { $_ }\n\n  $hasErrors = $false\n\n  foreach ($id in $PromoteToChannelsIds) {\n    if (($id -ne 0) -and ($id -notin $AvailableChannelIds)) {\n      Write-PipelineTaskError -Message \"Channel $id is not present in the post-build YAML configuration! This is an error scenario. Please contact @dnceng.\"\n      $hasErrors = $true\n    }\n  }\n\n  # The `Write-PipelineTaskError` doesn't error the script and we might report several errors\n  # in the previous lines. The check below makes sure that we return an error state from the\n  # script if we reported any validation error\n  if ($hasErrors) {\n    ExitWithExitCode 1 \n  }\n\n  Write-Host 'done.'\n} \ncatch {\n  Write-Host $_\n  Write-PipelineTelemetryError -Category 'CheckChannelConsistency' -Message \"There was an error while trying to check consistency of Maestro default channels for the build and post-build YAML configuration.\"\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/post-build/nuget-validation.ps1",
    "content": "# This script validates NuGet package metadata information using this \n# tool: https://github.com/NuGet/NuGetGallery/tree/jver-verify/src/VerifyMicrosoftPackage\n\nparam(\n  [Parameter(Mandatory=$true)][string] $PackagesPath # Path to where the packages to be validated are\n)\n\n# `tools.ps1` checks $ci to perform some actions. Since the post-build\n# scripts don't necessarily execute in the same agent that run the\n# build.ps1/sh script this variable isn't automatically set.\n$ci = $true\n$disableConfigureToolsetImport = $true\n. $PSScriptRoot\\..\\tools.ps1\n\ntry {\n  & $PSScriptRoot\\nuget-verification.ps1 ${PackagesPath}\\*.nupkg\n} \ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'NuGetValidation' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/post-build/nuget-verification.ps1",
    "content": "<#\n.SYNOPSIS\n    Verifies that Microsoft NuGet packages have proper metadata.\n.DESCRIPTION\n    Downloads a verification tool and runs metadata validation on the provided NuGet packages. This script writes an\n    error if any of the provided packages fail validation. All arguments provided to this PowerShell script that do not\n    match PowerShell parameters are passed on to the verification tool downloaded during the execution of this script.\n.PARAMETER NuGetExePath\n    The path to the nuget.exe binary to use. If not provided, nuget.exe will be downloaded into the -DownloadPath\n    directory.\n.PARAMETER PackageSource\n    The package source to use to download the verification tool. If not provided, nuget.org will be used.\n.PARAMETER DownloadPath\n    The directory path to download the verification tool and nuget.exe to. If not provided,\n    %TEMP%\\NuGet.VerifyNuGetPackage will be used.\n.PARAMETER args\n    Arguments that will be passed to the verification tool.\n.EXAMPLE\n    PS> .\\verify.ps1 *.nupkg\n    Verifies the metadata of all .nupkg files in the currect working directory.\n.EXAMPLE\n    PS> .\\verify.ps1 --help\n    Displays the help text of the downloaded verifiction tool.\n.LINK\n    https://github.com/NuGet/NuGetGallery/blob/master/src/VerifyMicrosoftPackage/README.md\n#>\n\n# This script was copied from https://github.com/NuGet/NuGetGallery/blob/3e25ad135146676bcab0050a516939d9958bfa5d/src/VerifyMicrosoftPackage/verify.ps1\n\n[CmdletBinding(PositionalBinding = $false)]\nparam(\n   [string]$NuGetExePath,\n   [string]$PackageSource = \"https://api.nuget.org/v3/index.json\",\n   [string]$DownloadPath,\n   [Parameter(ValueFromRemainingArguments = $true)]\n   [string[]]$args\n)\n\n# The URL to download nuget.exe.\n$nugetExeUrl = \"https://dist.nuget.org/win-x86-commandline/v4.9.4/nuget.exe\"\n\n# The package ID of the verification tool.\n$packageId = \"NuGet.VerifyMicrosoftPackage\"\n\n# The location that nuget.exe and the verification tool will be downloaded to.\nif (!$DownloadPath) {\n    $DownloadPath = (Join-Path $env:TEMP \"NuGet.VerifyMicrosoftPackage\")\n}\n\n$fence = New-Object -TypeName string -ArgumentList '=', 80\n\n# Create the download directory, if it doesn't already exist.\nif (!(Test-Path $DownloadPath)) {\n    New-Item -ItemType Directory $DownloadPath | Out-Null\n}\nWrite-Host \"Using download path: $DownloadPath\"\n\nif ($NuGetExePath) {\n    $nuget = $NuGetExePath\n} else {\n    $downloadedNuGetExe = Join-Path $DownloadPath \"nuget.exe\"\n    \n    # Download nuget.exe, if it doesn't already exist.\n    if (!(Test-Path $downloadedNuGetExe)) {\n        Write-Host \"Downloading nuget.exe from $nugetExeUrl...\"\n        $ProgressPreference = 'SilentlyContinue'\n        try {\n            Invoke-WebRequest $nugetExeUrl -OutFile $downloadedNuGetExe\n            $ProgressPreference = 'Continue'\n        } catch {\n            $ProgressPreference = 'Continue'\n            Write-Error $_\n            Write-Error \"nuget.exe failed to download.\"\n            exit\n        }\n    }\n\n    $nuget = $downloadedNuGetExe\n}\n\nWrite-Host \"Using nuget.exe path: $nuget\"\nWrite-Host \" \"\n\n# Download the latest version of the verification tool.\nWrite-Host \"Downloading the latest version of $packageId from $packageSource...\"\nWrite-Host $fence\n& $nuget install $packageId `\n    -Prerelease `\n    -OutputDirectory $DownloadPath `\n    -Source $PackageSource\nWrite-Host $fence\nWrite-Host \" \"\n\nif ($LASTEXITCODE -ne 0) {\n    Write-Error \"nuget.exe failed to fetch the verify tool.\"\n    exit\n}\n\n# Find the most recently downloaded tool\nWrite-Host \"Finding the most recently downloaded verification tool.\"\n$verifyProbePath = Join-Path $DownloadPath \"$packageId.*\"\n$verifyPath = Get-ChildItem -Path $verifyProbePath -Directory `\n    | Sort-Object -Property LastWriteTime -Descending `\n    | Select-Object -First 1\n$verify = Join-Path $verifyPath \"tools\\NuGet.VerifyMicrosoftPackage.exe\"\nWrite-Host \"Using verification tool: $verify\"\nWrite-Host \" \"\n\n# Execute the verification tool.\nWrite-Host \"Executing the verify tool...\"\nWrite-Host $fence\n& $verify $args\nWrite-Host $fence\nWrite-Host \" \"\n\n# Respond to the exit code.\nif ($LASTEXITCODE -ne 0) {\n    Write-Error \"The verify tool found some problems.\"\n} else {\n    Write-Output \"The verify tool succeeded.\"\n}\n"
  },
  {
    "path": "eng/common/post-build/publish-using-darc.ps1",
    "content": "param(\n  [Parameter(Mandatory=$true)][int] $BuildId,\n  [Parameter(Mandatory=$true)][int] $PublishingInfraVersion,\n  [Parameter(Mandatory=$true)][string] $AzdoToken,\n  [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net',\n  [Parameter(Mandatory=$true)][string] $WaitPublishingFinish,\n  [Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters,\n  [Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters,\n  [Parameter(Mandatory=$false)][string] $RequireDefaultChannels\n)\n\ntry {\n  # `tools.ps1` checks $ci to perform some actions. Since the post-build\n  # scripts don't necessarily execute in the same agent that run the\n  # build.ps1/sh script this variable isn't automatically set.\n  $ci = $true\n  $disableConfigureToolsetImport = $true\n  . $PSScriptRoot\\..\\tools.ps1\n\n  $darc = Get-Darc\n\n  $optionalParams = [System.Collections.ArrayList]::new()\n\n  if (\"\" -ne $ArtifactsPublishingAdditionalParameters) {\n    $optionalParams.Add(\"--artifact-publishing-parameters\") | Out-Null\n    $optionalParams.Add($ArtifactsPublishingAdditionalParameters) | Out-Null\n  }\n\n  if (\"\" -ne $SymbolPublishingAdditionalParameters) {\n    $optionalParams.Add(\"--symbol-publishing-parameters\") | Out-Null\n    $optionalParams.Add($SymbolPublishingAdditionalParameters) | Out-Null\n  }\n\n  if (\"false\" -eq $WaitPublishingFinish) {\n    $optionalParams.Add(\"--no-wait\") | Out-Null\n  }\n  \n  if (\"true\" -eq $RequireDefaultChannels) {\n    $optionalParams.Add(\"--default-channels-required\") | Out-Null\n  }\n\n  & $darc add-build-to-channel `\n    --id $buildId `\n    --publishing-infra-version $PublishingInfraVersion `\n    --default-channels `\n    --source-branch main `\n    --azdev-pat \"$AzdoToken\" `\n    --bar-uri \"$MaestroApiEndPoint\" `\n    --ci `\n    --verbose `\n\t@optionalParams\n\n  if ($LastExitCode -ne 0) {\n    Write-Host \"Problems using Darc to promote build ${buildId} to default channels. Stopping execution...\"\n    exit 1\n  }\n\n  Write-Host 'done.'\n}\ncatch {\n  Write-Host $_\n  Write-PipelineTelemetryError -Category 'PromoteBuild' -Message \"There was an error while trying to publish build '$BuildId' to default channels.\"\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/post-build/redact-logs.ps1",
    "content": "[CmdletBinding(PositionalBinding=$False)]\nparam(\n  [Parameter(Mandatory=$true, Position=0)][string] $InputPath,\n  [Parameter(Mandatory=$true)][string] $BinlogToolVersion,\n  [Parameter(Mandatory=$false)][string] $DotnetPath,\n  [Parameter(Mandatory=$false)][string] $PackageFeed = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json',\n  # File with strings to redact - separated by newlines.\n  #  For comments start the line with '# ' - such lines are ignored \n  [Parameter(Mandatory=$false)][string] $TokensFilePath,\n  [Parameter(ValueFromRemainingArguments=$true)][String[]]$TokensToRedact\n)\n\ntry {\n  $ErrorActionPreference = 'Stop'\n  Set-StrictMode -Version 2.0\n\n  # `tools.ps1` checks $ci to perform some actions. Since the post-build\n  # scripts don't necessarily execute in the same agent that run the\n  # build.ps1/sh script this variable isn't automatically set.\n  $ci = $true\n  $disableConfigureToolsetImport = $true\n  . $PSScriptRoot\\..\\tools.ps1\n\n  $packageName = 'binlogtool'\n\n  $dotnet = $DotnetPath\n\n  if (!$dotnet) {\n    $dotnetRoot = InitializeDotNetCli -install:$true\n    $dotnet = \"$dotnetRoot\\dotnet.exe\"\n  }\n  \n  $toolList = & \"$dotnet\" tool list -g\n\n  if ($toolList -like \"*$packageName*\") {\n    & \"$dotnet\" tool uninstall $packageName -g\n  }\n\n  $toolPath  = \"$PSScriptRoot\\..\\..\\..\\.tools\"\n  $verbosity = 'minimal'\n  \n  New-Item -ItemType Directory -Force -Path $toolPath\n  \n  Push-Location -Path $toolPath\n\n  try {\n    Write-Host \"Installing Binlog redactor CLI...\"\n    Write-Host \"'$dotnet' new tool-manifest\"\n    & \"$dotnet\" new tool-manifest\n    Write-Host \"'$dotnet' tool install $packageName --local --add-source '$PackageFeed' -v $verbosity --version $BinlogToolVersion\"\n    & \"$dotnet\" tool install $packageName --local --add-source \"$PackageFeed\" -v $verbosity --version $BinlogToolVersion\n\n    if (Test-Path $TokensFilePath) {\n        Write-Host \"Adding additional sensitive data for redaction from file: \" $TokensFilePath\n        $TokensToRedact += Get-Content -Path $TokensFilePath | Foreach {$_.Trim()} | Where { $_ -notmatch \"^# \" }\n    }\n\n    $optionalParams = [System.Collections.ArrayList]::new()\n  \n    Foreach ($p in $TokensToRedact)\n    {\n      if($p -match '^\\$\\(.*\\)$')\n      {\n        Write-Host (\"Ignoring token {0} as it is probably unexpanded AzDO variable\"  -f $p)\n      }          \n      elseif($p)\n      {\n        $optionalParams.Add(\"-p:\" + $p) | Out-Null\n      }\n    }\n\n    & $dotnet binlogtool redact --input:$InputPath --recurse --in-place `\n      @optionalParams\n\n    if ($LastExitCode -ne 0) {\n      Write-PipelineTelemetryError -Category 'Redactor' -Type 'warning' -Message \"Problems using Redactor tool (exit code: $LastExitCode). But ignoring them now.\"\n    }\n  }\n  finally {\n    Pop-Location\n  }\n\n  Write-Host 'done.'\n} \ncatch {\n  Write-Host $_\n  Write-PipelineTelemetryError -Category 'Redactor' -Message \"There was an error while trying to redact logs. Error: $_\"\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/post-build/sourcelink-validation.ps1",
    "content": "param(\n  [Parameter(Mandatory=$true)][string] $InputPath,              # Full path to directory where Symbols.NuGet packages to be checked are stored\n  [Parameter(Mandatory=$true)][string] $ExtractPath,            # Full path to directory where the packages will be extracted during validation\n  [Parameter(Mandatory=$false)][string] $GHRepoName,            # GitHub name of the repo including the Org. E.g., dotnet/arcade\n  [Parameter(Mandatory=$false)][string] $GHCommit,              # GitHub commit SHA used to build the packages\n  [Parameter(Mandatory=$true)][string] $SourcelinkCliVersion    # Version of SourceLink CLI to use\n)\n\n$ErrorActionPreference = 'Stop'\nSet-StrictMode -Version 2.0\n\n# `tools.ps1` checks $ci to perform some actions. Since the post-build\n# scripts don't necessarily execute in the same agent that run the\n# build.ps1/sh script this variable isn't automatically set.\n$ci = $true\n$disableConfigureToolsetImport = $true\n. $PSScriptRoot\\..\\tools.ps1\n\n# Cache/HashMap (File -> Exist flag) used to consult whether a file exist \n# in the repository at a specific commit point. This is populated by inserting\n# all files present in the repo at a specific commit point.\n$global:RepoFiles = @{}\n\n# Maximum number of jobs to run in parallel\n$MaxParallelJobs = 16\n\n$MaxRetries = 5\n$RetryWaitTimeInSeconds = 30\n\n# Wait time between check for system load\n$SecondsBetweenLoadChecks = 10\n\nif (!$InputPath -or !(Test-Path $InputPath)){\n  Write-Host \"No files to validate.\"\n  ExitWithExitCode 0\n}\n\n$ValidatePackage = {\n  param( \n    [string] $PackagePath                                 # Full path to a Symbols.NuGet package\n  )\n\n  . $using:PSScriptRoot\\..\\tools.ps1\n\n  # Ensure input file exist\n  if (!(Test-Path $PackagePath)) {\n    Write-Host \"Input file does not exist: $PackagePath\"\n    return [pscustomobject]@{\n      result = 1\n      packagePath = $PackagePath\n    }\n  }\n\n  # Extensions for which we'll look for SourceLink information\n  # For now we'll only care about Portable & Embedded PDBs\n  $RelevantExtensions = @('.dll', '.exe', '.pdb')\n \n  Write-Host -NoNewLine 'Validating ' ([System.IO.Path]::GetFileName($PackagePath)) '...'\n\n  $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath)\n  $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId\n  $FailedFiles = 0\n\n  Add-Type -AssemblyName System.IO.Compression.FileSystem\n\n  [System.IO.Directory]::CreateDirectory($ExtractPath)  | Out-Null\n\n  try {\n    $zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath)\n\n    $zip.Entries | \n      Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} |\n        ForEach-Object {\n          $FileName = $_.FullName\n          $Extension = [System.IO.Path]::GetExtension($_.Name)\n          $FakeName = -Join((New-Guid), $Extension)\n          $TargetFile = Join-Path -Path $ExtractPath -ChildPath $FakeName \n\n          # We ignore resource DLLs\n          if ($FileName.EndsWith('.resources.dll')) {\n            return [pscustomobject]@{\n              result = 0\n              packagePath = $PackagePath\n            }\n          }\n\n          [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile, $true)\n\n          $ValidateFile = {\n            param( \n              [string] $FullPath,                                # Full path to the module that has to be checked\n              [string] $RealPath,\n              [ref] $FailedFiles\n            )\n\n            $sourcelinkExe = \"$env:USERPROFILE\\.dotnet\\tools\"\n            $sourcelinkExe = Resolve-Path \"$sourcelinkExe\\sourcelink.exe\"\n            $SourceLinkInfos = & $sourcelinkExe print-urls $FullPath | Out-String\n\n            if ($LASTEXITCODE -eq 0 -and -not ([string]::IsNullOrEmpty($SourceLinkInfos))) {\n              $NumFailedLinks = 0\n\n              # We only care about Http addresses\n              $Matches = (Select-String '(http[s]?)(:\\/\\/)([^\\s,]+)' -Input $SourceLinkInfos -AllMatches).Matches\n\n              if ($Matches.Count -ne 0) {\n                $Matches.Value |\n                  ForEach-Object {\n                    $Link = $_\n                    $CommitUrl = \"https://raw.githubusercontent.com/${using:GHRepoName}/${using:GHCommit}/\"\n                    \n                    $FilePath = $Link.Replace($CommitUrl, \"\")\n                    $Status = 200\n                    $Cache = $using:RepoFiles\n\n                    $attempts = 0\n\n                    while ($attempts -lt $using:MaxRetries) {\n                      if ( !($Cache.ContainsKey($FilePath)) ) {\n                        try {\n                          $Uri = $Link -as [System.URI]\n                        \n                          if ($Link -match \"submodules\") {\n                            # Skip submodule links until sourcelink properly handles submodules\n                            $Status = 200\n                          }\n                          elseif ($Uri.AbsoluteURI -ne $null -and ($Uri.Host -match 'github' -or $Uri.Host -match 'githubusercontent')) {\n                            # Only GitHub links are valid\n                            $Status = (Invoke-WebRequest -Uri $Link -UseBasicParsing -Method HEAD -TimeoutSec 5).StatusCode\n                          }\n                          else {\n                            # If it's not a github link, we want to break out of the loop and not retry.\n                            $Status = 0\n                            $attempts = $using:MaxRetries\n                          }\n                        }\n                        catch {\n                          Write-Host $_\n                          $Status = 0\n                        }\n                      }\n\n                      if ($Status -ne 200) {\n                        $attempts++\n                        \n                        if  ($attempts -lt $using:MaxRetries)\n                        {\n                          $attemptsLeft = $using:MaxRetries - $attempts\n                          Write-Warning \"Download failed, $attemptsLeft attempts remaining, will retry in $using:RetryWaitTimeInSeconds seconds\"\n                          Start-Sleep -Seconds $using:RetryWaitTimeInSeconds\n                        }\n                        else {\n                          if ($NumFailedLinks -eq 0) {\n                            if ($FailedFiles.Value -eq 0) {\n                              Write-Host\n                            }\n  \n                            Write-Host \"`tFile $RealPath has broken links:\"\n                          }\n  \n                          Write-Host \"`t`tFailed to retrieve $Link\"\n  \n                          $NumFailedLinks++\n                        }\n                      }\n                      else {\n                        break\n                      }\n                    }\n                  }\n              }\n\n              if ($NumFailedLinks -ne 0) {\n                $FailedFiles.value++\n                $global:LASTEXITCODE = 1\n              }\n            }\n          }\n        \n          &$ValidateFile $TargetFile $FileName ([ref]$FailedFiles)\n        }\n  }\n  catch {\n    Write-Host $_\n  }\n  finally {\n    $zip.Dispose() \n  }\n\n  if ($FailedFiles -eq 0) {\n    Write-Host 'Passed.'\n    return [pscustomobject]@{\n      result = 0\n      packagePath = $PackagePath\n    }\n  }\n  else {\n    Write-PipelineTelemetryError -Category 'SourceLink' -Message \"$PackagePath has broken SourceLink links.\"\n    return [pscustomobject]@{\n      result = 1\n      packagePath = $PackagePath\n    }\n  }\n}\n\nfunction CheckJobResult(\n    $result, \n    $packagePath,\n    [ref]$ValidationFailures,\n    [switch]$logErrors) {\n  if ($result -ne '0') {\n    if ($logErrors) {\n      Write-PipelineTelemetryError -Category 'SourceLink' -Message \"$packagePath has broken SourceLink links.\"\n    }\n    $ValidationFailures.Value++\n  }\n}\n\nfunction ValidateSourceLinkLinks {\n  if ($GHRepoName -ne '' -and !($GHRepoName -Match '^[^\\s\\/]+/[^\\s\\/]+$')) {\n    if (!($GHRepoName -Match '^[^\\s-]+-[^\\s]+$')) {\n      Write-PipelineTelemetryError -Category 'SourceLink' -Message \"GHRepoName should be in the format <org>/<repo> or <org>-<repo>. '$GHRepoName'\"\n      ExitWithExitCode 1\n    }\n    else {\n      $GHRepoName = $GHRepoName -replace '^([^\\s-]+)-([^\\s]+)$', '$1/$2';\n    }\n  }\n\n  if ($GHCommit -ne '' -and !($GHCommit -Match '^[0-9a-fA-F]{40}$')) {\n    Write-PipelineTelemetryError -Category 'SourceLink' -Message \"GHCommit should be a 40 chars hexadecimal string. '$GHCommit'\"\n    ExitWithExitCode 1\n  }\n\n  if ($GHRepoName -ne '' -and $GHCommit -ne '') {\n    $RepoTreeURL = -Join('http://api.github.com/repos/', $GHRepoName, '/git/trees/', $GHCommit, '?recursive=1')\n    $CodeExtensions = @('.cs', '.vb', '.fs', '.fsi', '.fsx', '.fsscript')\n\n    try {\n      # Retrieve the list of files in the repo at that particular commit point and store them in the RepoFiles hash\n      $Data = Invoke-WebRequest $RepoTreeURL -UseBasicParsing | ConvertFrom-Json | Select-Object -ExpandProperty tree\n  \n      foreach ($file in $Data) {\n        $Extension = [System.IO.Path]::GetExtension($file.path)\n\n        if ($CodeExtensions.Contains($Extension)) {\n          $RepoFiles[$file.path] = 1\n        }\n      }\n    }\n    catch {\n      Write-Host \"Problems downloading the list of files from the repo. Url used: $RepoTreeURL . Execution will proceed without caching.\"\n    }\n  }\n  elseif ($GHRepoName -ne '' -or $GHCommit -ne '') {\n    Write-Host 'For using the http caching mechanism both GHRepoName and GHCommit should be informed.'\n  }\n  \n  if (Test-Path $ExtractPath) {\n    Remove-Item $ExtractPath -Force -Recurse -ErrorAction SilentlyContinue\n  }\n\n  $ValidationFailures = 0\n\n  # Process each NuGet package in parallel\n  Get-ChildItem \"$InputPath\\*.symbols.nupkg\" |\n    ForEach-Object {\n      Write-Host \"Starting $($_.FullName)\"\n      Start-Job -ScriptBlock $ValidatePackage -ArgumentList $_.FullName | Out-Null\n      $NumJobs = @(Get-Job -State 'Running').Count\n      \n      while ($NumJobs -ge $MaxParallelJobs) {\n        Write-Host \"There are $NumJobs validation jobs running right now. Waiting $SecondsBetweenLoadChecks seconds to check again.\"\n        sleep $SecondsBetweenLoadChecks\n        $NumJobs = @(Get-Job -State 'Running').Count\n      }\n\n      foreach ($Job in @(Get-Job -State 'Completed')) {\n        $jobResult = Wait-Job -Id $Job.Id | Receive-Job\n        CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$ValidationFailures) -LogErrors\n        Remove-Job -Id $Job.Id\n      }\n    }\n\n  foreach ($Job in @(Get-Job)) {\n    $jobResult = Wait-Job -Id $Job.Id | Receive-Job\n    CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$ValidationFailures)\n    Remove-Job -Id $Job.Id\n  }\n  if ($ValidationFailures -gt 0) {\n    Write-PipelineTelemetryError -Category 'SourceLink' -Message \"$ValidationFailures package(s) failed validation.\"\n    ExitWithExitCode 1\n  }\n}\n\nfunction InstallSourcelinkCli {\n  $sourcelinkCliPackageName = 'sourcelink'\n\n  $dotnetRoot = InitializeDotNetCli -install:$true\n  $dotnet = \"$dotnetRoot\\dotnet.exe\"\n  $toolList = & \"$dotnet\" tool list --global\n\n  if (($toolList -like \"*$sourcelinkCliPackageName*\") -and ($toolList -like \"*$sourcelinkCliVersion*\")) {\n    Write-Host \"SourceLink CLI version $sourcelinkCliVersion is already installed.\"\n  }\n  else {\n    Write-Host \"Installing SourceLink CLI version $sourcelinkCliVersion...\"\n    Write-Host 'You may need to restart your command window if this is the first dotnet tool you have installed.'\n    & \"$dotnet\" tool install $sourcelinkCliPackageName --version $sourcelinkCliVersion --verbosity \"minimal\" --global \n  }\n}\n\ntry {\n  InstallSourcelinkCli\n\n  foreach ($Job in @(Get-Job)) {\n    Remove-Job -Id $Job.Id\n  }\n\n  ValidateSourceLinkLinks \n}\ncatch {\n  Write-Host $_.Exception\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'SourceLink' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/post-build/symbols-validation.ps1",
    "content": "param(\n  [Parameter(Mandatory = $true)][string] $InputPath, # Full path to directory where NuGet packages to be checked are stored\n  [Parameter(Mandatory = $true)][string] $ExtractPath, # Full path to directory where the packages will be extracted during validation\n  [Parameter(Mandatory = $true)][string] $DotnetSymbolVersion, # Version of dotnet symbol to use\n  [Parameter(Mandatory = $false)][switch] $CheckForWindowsPdbs, # If we should check for the existence of windows pdbs in addition to portable PDBs\n  [Parameter(Mandatory = $false)][switch] $ContinueOnError, # If we should keep checking symbols after an error\n  [Parameter(Mandatory = $false)][switch] $Clean,           # Clean extracted symbols directory after checking symbols\n  [Parameter(Mandatory = $false)][string] $SymbolExclusionFile  # Exclude the symbols in the file from publishing to symbol server\n)\n\n. $PSScriptRoot\\..\\tools.ps1\n# Maximum number of jobs to run in parallel\n$MaxParallelJobs = 16\n\n# Max number of retries\n$MaxRetry = 5\n\n# Wait time between check for system load\n$SecondsBetweenLoadChecks = 10\n\n# Set error codes\nSet-Variable -Name \"ERROR_BADEXTRACT\" -Option Constant -Value -1\nSet-Variable -Name \"ERROR_FILEDOESNOTEXIST\" -Option Constant -Value -2\n\n$WindowsPdbVerificationParam = \"\"\nif ($CheckForWindowsPdbs) {\n  $WindowsPdbVerificationParam = \"--windows-pdbs\"\n}\n\n$ExclusionSet = New-Object System.Collections.Generic.HashSet[string];\n\nif (!$InputPath -or !(Test-Path $InputPath)){\n  Write-Host \"No symbols to validate.\"\n  ExitWithExitCode 0\n}\n\n#Check if the path exists\nif ($SymbolExclusionFile -and (Test-Path $SymbolExclusionFile)){\n  [string[]]$Exclusions = Get-Content \"$SymbolExclusionFile\"\n  $Exclusions | foreach { if($_ -and $_.Trim()){$ExclusionSet.Add($_)} }\n}\nelse{\n  Write-Host \"Symbol Exclusion file does not exists. No symbols to exclude.\"\n}\n\n$CountMissingSymbols = {\n  param( \n    [string] $PackagePath, # Path to a NuGet package\n    [string] $WindowsPdbVerificationParam # If we should check for the existence of windows pdbs in addition to portable PDBs\n  )\n\n  Add-Type -AssemblyName System.IO.Compression.FileSystem\n\n  Write-Host \"Validating $PackagePath \"\n\n  # Ensure input file exist\n  if (!(Test-Path $PackagePath)) {\n    Write-PipelineTaskError \"Input file does not exist: $PackagePath\"\n    return [pscustomobject]@{\n      result      = $using:ERROR_FILEDOESNOTEXIST\n      packagePath = $PackagePath\n    }\n  }\n  \n  # Extensions for which we'll look for symbols\n  $RelevantExtensions = @('.dll', '.exe', '.so', '.dylib')\n\n  # How many files are missing symbol information\n  $MissingSymbols = 0\n\n  $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath)\n  $PackageGuid = New-Guid\n  $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageGuid\n  $SymbolsPath = Join-Path -Path $ExtractPath -ChildPath 'Symbols'\n  \n  try {\n    [System.IO.Compression.ZipFile]::ExtractToDirectory($PackagePath, $ExtractPath)\n  }\n  catch {\n    Write-Host \"Something went wrong extracting $PackagePath\"\n    Write-Host $_\n    return [pscustomobject]@{\n      result      = $using:ERROR_BADEXTRACT\n      packagePath = $PackagePath\n    }\n  }\n\n  Get-ChildItem -Recurse $ExtractPath |\n  Where-Object { $RelevantExtensions -contains $_.Extension } |\n  ForEach-Object {\n    $FileName = $_.FullName\n    if ($FileName -Match '\\\\ref\\\\') {\n      Write-Host \"`t Ignoring reference assembly file \" $FileName\n      return\n    }\n\n    $FirstMatchingSymbolDescriptionOrDefault = {\n      param( \n        [string] $FullPath, # Full path to the module that has to be checked\n        [string] $TargetServerParam, # Parameter to pass to `Symbol Tool` indicating the server to lookup for symbols\n        [string] $WindowsPdbVerificationParam, # Parameter to pass to potential check for windows-pdbs.\n        [string] $SymbolsPath\n      )\n\n      $FileName = [System.IO.Path]::GetFileName($FullPath)\n      $Extension = [System.IO.Path]::GetExtension($FullPath)\n\n      # Those below are potential symbol files that the `dotnet symbol` might\n      # return. Which one will be returned depend on the type of file we are\n      # checking and which type of file was uploaded.\n\n      # The file itself is returned\n      $SymbolPath = $SymbolsPath + '\\' + $FileName\n\n      # PDB file for the module\n      $PdbPath = $SymbolPath.Replace($Extension, '.pdb')\n\n      # PDB file for R2R module (created by crossgen)\n      $NGenPdb = $SymbolPath.Replace($Extension, '.ni.pdb')\n\n      # DBG file for a .so library\n      $SODbg = $SymbolPath.Replace($Extension, '.so.dbg')\n\n      # DWARF file for a .dylib\n      $DylibDwarf = $SymbolPath.Replace($Extension, '.dylib.dwarf')\n\n      $dotnetSymbolExe = \"$env:USERPROFILE\\.dotnet\\tools\"\n      $dotnetSymbolExe = Resolve-Path \"$dotnetSymbolExe\\dotnet-symbol.exe\"\n\n      $totalRetries = 0\n\n      while ($totalRetries -lt $using:MaxRetry) {\n\n        # Save the output and get diagnostic output\n        $output = & $dotnetSymbolExe --symbols --modules $WindowsPdbVerificationParam $TargetServerParam $FullPath -o $SymbolsPath --diagnostics | Out-String\n\n        if ((Test-Path $PdbPath) -and (Test-path $SymbolPath)) {\n          return 'Module and PDB for Module'\n        }\n        elseif ((Test-Path $NGenPdb) -and (Test-Path $PdbPath) -and (Test-Path $SymbolPath)) {\n          return 'Dll, PDB and NGen PDB'\n        }\n        elseif ((Test-Path $SODbg) -and (Test-Path $SymbolPath)) {\n          return 'So and DBG for SO'\n        }  \n        elseif ((Test-Path $DylibDwarf) -and (Test-Path $SymbolPath)) {\n          return 'Dylib and Dwarf for Dylib'\n        }  \n        elseif (Test-Path $SymbolPath) {\n          return 'Module'\n        }\n        else\n        {\n          $totalRetries++\n        }\n      }\n      \n      return $null\n    }\n\n    $FileRelativePath = $FileName.Replace(\"$ExtractPath\\\", \"\")\n    if (($($using:ExclusionSet) -ne $null) -and ($($using:ExclusionSet).Contains($FileRelativePath) -or ($($using:ExclusionSet).Contains($FileRelativePath.Replace(\"\\\", \"/\"))))){\n      Write-Host \"Skipping $FileName from symbol validation\"\n    }\n\n    else {\n      $FileGuid = New-Guid\n      $ExpandedSymbolsPath = Join-Path -Path $SymbolsPath -ChildPath $FileGuid\n\n      $SymbolsOnMSDL = & $FirstMatchingSymbolDescriptionOrDefault `\n          -FullPath $FileName `\n          -TargetServerParam '--microsoft-symbol-server' `\n          -SymbolsPath \"$ExpandedSymbolsPath-msdl\" `\n          -WindowsPdbVerificationParam $WindowsPdbVerificationParam\n      $SymbolsOnSymWeb = & $FirstMatchingSymbolDescriptionOrDefault `\n          -FullPath $FileName `\n          -TargetServerParam '--internal-server' `\n          -SymbolsPath \"$ExpandedSymbolsPath-symweb\" `\n          -WindowsPdbVerificationParam $WindowsPdbVerificationParam\n\n      Write-Host -NoNewLine \"`t Checking file \" $FileName \"... \"\n  \n      if ($SymbolsOnMSDL -ne $null -and $SymbolsOnSymWeb -ne $null) {\n        Write-Host \"Symbols found on MSDL ($SymbolsOnMSDL) and SymWeb ($SymbolsOnSymWeb)\"\n      }\n      else {\n        $MissingSymbols++\n\n        if ($SymbolsOnMSDL -eq $null -and $SymbolsOnSymWeb -eq $null) {\n          Write-Host 'No symbols found on MSDL or SymWeb!'\n        }\n        else {\n          if ($SymbolsOnMSDL -eq $null) {\n            Write-Host 'No symbols found on MSDL!'\n          }\n          else {\n            Write-Host 'No symbols found on SymWeb!'\n          }\n        }\n      }\n    }\n  }\n  \n  if ($using:Clean) {\n    Remove-Item $ExtractPath -Recurse -Force\n  }\n  \n  Pop-Location\n\n  return [pscustomobject]@{\n    result      = $MissingSymbols\n    packagePath = $PackagePath\n  }\n}\n\nfunction CheckJobResult(\n  $result, \n  $packagePath,\n  [ref]$DupedSymbols,\n  [ref]$TotalFailures) {\n  if ($result -eq $ERROR_BADEXTRACT) {\n    Write-PipelineTelemetryError -Category 'CheckSymbols' -Message \"$packagePath has duplicated symbol files\"\n    $DupedSymbols.Value++\n  } \n  elseif ($result -eq $ERROR_FILEDOESNOTEXIST) {\n    Write-PipelineTelemetryError -Category 'CheckSymbols' -Message \"$packagePath does not exist\"\n    $TotalFailures.Value++\n  }\n  elseif ($result -gt '0') {\n    Write-PipelineTelemetryError -Category 'CheckSymbols' -Message \"Missing symbols for $result modules in the package $packagePath\"\n    $TotalFailures.Value++\n  }\n  else {\n    Write-Host \"All symbols verified for package $packagePath\"\n  }\n}\n\nfunction CheckSymbolsAvailable {\n  if (Test-Path $ExtractPath) {\n    Remove-Item $ExtractPath -Force  -Recurse -ErrorAction SilentlyContinue\n  }\n\n  $TotalPackages = 0\n  $TotalFailures = 0\n  $DupedSymbols = 0\n\n  Get-ChildItem \"$InputPath\\*.nupkg\" |\n    ForEach-Object {\n      $FileName = $_.Name\n      $FullName = $_.FullName\n\n      # These packages from Arcade-Services include some native libraries that\n      # our current symbol uploader can't handle. Below is a workaround until\n      # we get issue: https://github.com/dotnet/arcade/issues/2457 sorted.\n      if ($FileName -Match 'Microsoft\\.DotNet\\.Darc\\.') {\n        Write-Host \"Ignoring Arcade-services file: $FileName\"\n        Write-Host\n        return\n      }\n      elseif ($FileName -Match 'Microsoft\\.DotNet\\.Maestro\\.Tasks\\.') {\n        Write-Host \"Ignoring Arcade-services file: $FileName\"\n        Write-Host\n        return\n      }\n\n      $TotalPackages++\n\n      Start-Job -ScriptBlock $CountMissingSymbols -ArgumentList @($FullName,$WindowsPdbVerificationParam) | Out-Null\n\n      $NumJobs = @(Get-Job -State 'Running').Count\n\n      while ($NumJobs -ge $MaxParallelJobs) {\n        Write-Host \"There are $NumJobs validation jobs running right now. Waiting $SecondsBetweenLoadChecks seconds to check again.\"\n        sleep $SecondsBetweenLoadChecks\n        $NumJobs = @(Get-Job -State 'Running').Count\n      }\n\n      foreach ($Job in @(Get-Job -State 'Completed')) {\n        $jobResult = Wait-Job -Id $Job.Id | Receive-Job\n        CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$DupedSymbols) ([ref]$TotalFailures)\n        Remove-Job -Id $Job.Id\n      }\n      Write-Host\n    }\n\n  foreach ($Job in @(Get-Job)) {\n    $jobResult = Wait-Job -Id $Job.Id | Receive-Job\n    CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$DupedSymbols) ([ref]$TotalFailures)\n  }\n\n  if ($TotalFailures -gt 0 -or $DupedSymbols -gt 0) {\n    if ($TotalFailures -gt 0) {\n      Write-PipelineTelemetryError -Category 'CheckSymbols' -Message \"Symbols missing for $TotalFailures/$TotalPackages packages\"\n    }\n\n    if ($DupedSymbols -gt 0) {\n      Write-PipelineTelemetryError -Category 'CheckSymbols' -Message \"$DupedSymbols/$TotalPackages packages had duplicated symbol files and could not be extracted\"\n    }\n    \n    ExitWithExitCode 1\n  }\n  else {\n    Write-Host \"All symbols validated!\"\n  }\n}\n\nfunction InstallDotnetSymbol {\n  $dotnetSymbolPackageName = 'dotnet-symbol'\n\n  $dotnetRoot = InitializeDotNetCli -install:$true\n  $dotnet = \"$dotnetRoot\\dotnet.exe\"\n  $toolList = & \"$dotnet\" tool list --global\n\n  if (($toolList -like \"*$dotnetSymbolPackageName*\") -and ($toolList -like \"*$dotnetSymbolVersion*\")) {\n    Write-Host \"dotnet-symbol version $dotnetSymbolVersion is already installed.\"\n  }\n  else {\n    Write-Host \"Installing dotnet-symbol version $dotnetSymbolVersion...\"\n    Write-Host 'You may need to restart your command window if this is the first dotnet tool you have installed.'\n    & \"$dotnet\" tool install $dotnetSymbolPackageName --version $dotnetSymbolVersion --verbosity \"minimal\" --global\n  }\n}\n\ntry {\n  InstallDotnetSymbol\n\n  foreach ($Job in @(Get-Job)) {\n    Remove-Job -Id $Job.Id\n  }\n\n  CheckSymbolsAvailable\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'CheckSymbols' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/retain-build.ps1",
    "content": "\nParam(\n[Parameter(Mandatory=$true)][int] $buildId,\n[Parameter(Mandatory=$true)][string] $azdoOrgUri, \n[Parameter(Mandatory=$true)][string] $azdoProject,\n[Parameter(Mandatory=$true)][string] $token\n)\n\n$ErrorActionPreference = 'Stop'\nSet-StrictMode -Version 2.0\n\nfunction Get-AzDOHeaders(\n    [string] $token)\n{\n    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(\":${token}\"))\n    $headers = @{\"Authorization\"=\"Basic $base64AuthInfo\"}\n    return $headers\n}\n\nfunction Update-BuildRetention(\n    [string] $azdoOrgUri,\n    [string] $azdoProject,\n    [int] $buildId,\n    [string] $token)\n{\n    $headers = Get-AzDOHeaders -token $token\n    $requestBody = \"{\n        `\"keepForever`\": `\"true`\"\n    }\"\n\n    $requestUri = \"${azdoOrgUri}/${azdoProject}/_apis/build/builds/${buildId}?api-version=6.0\"\n    write-Host \"Attempting to retain build using the following URI: ${requestUri} ...\"\n\n    try {\n        Invoke-RestMethod -Uri $requestUri -Method Patch -Body $requestBody -Header $headers -contentType \"application/json\"\n        Write-Host \"Updated retention settings for build ${buildId}.\"\n    }\n    catch {\n        Write-Error \"Failed to update retention settings for build: $_.Exception.Response.StatusDescription\"\n        exit 1\n    }\n}\n\nUpdate-BuildRetention -azdoOrgUri $azdoOrgUri -azdoProject $azdoProject -buildId $buildId -token $token\nexit 0\n"
  },
  {
    "path": "eng/common/sdk-task.ps1",
    "content": "[CmdletBinding(PositionalBinding=$false)]\nParam(\n  [string] $configuration = 'Debug',\n  [string] $task,\n  [string] $verbosity = 'minimal',\n  [string] $msbuildEngine = $null,\n  [switch] $restore,\n  [switch] $prepareMachine,\n  [switch] $help,\n  [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties\n)\n\n$ci = $true\n$binaryLog = $true\n$warnAsError = $true\n\n. $PSScriptRoot\\tools.ps1\n\nfunction Print-Usage() {\n  Write-Host \"Common settings:\"\n  Write-Host \"  -task <value>           Name of Arcade task (name of a project in SdkTasks directory of the Arcade SDK package)\"\n  Write-Host \"  -restore                Restore dependencies\"\n  Write-Host \"  -verbosity <value>      Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]\"\n  Write-Host \"  -help                   Print help and exit\"\n  Write-Host \"\"\n\n  Write-Host \"Advanced settings:\"\n  Write-Host \"  -prepareMachine         Prepare machine for CI run\"\n  Write-Host \"  -msbuildEngine <value>  Msbuild engine to use to run build ('dotnet', 'vs', or unspecified).\"\n  Write-Host \"\"\n  Write-Host \"Command line arguments not listed above are passed thru to msbuild.\"\n}\n\nfunction Build([string]$target) {\n  $logSuffix = if ($target -eq 'Execute') { '' } else { \".$target\" }\n  $log = Join-Path $LogDir \"$task$logSuffix.binlog\"\n  $outputPath = Join-Path $ToolsetDir \"$task\\\"\n\n  MSBuild $taskProject `\n    /bl:$log `\n    /t:$target `\n    /p:Configuration=$configuration `\n    /p:RepoRoot=$RepoRoot `\n    /p:BaseIntermediateOutputPath=$outputPath `\n    /v:$verbosity `\n    @properties\n}\n\ntry {\n  if ($help -or (($null -ne $properties) -and ($properties.Contains('/help') -or $properties.Contains('/?')))) {\n    Print-Usage\n    exit 0\n  }\n\n  if ($task -eq \"\") {\n    Write-PipelineTelemetryError -Category 'Build' -Message \"Missing required parameter '-task <value>'\"\n    Print-Usage\n    ExitWithExitCode 1\n  }\n\n  if( $msbuildEngine -eq \"vs\") {\n    # Ensure desktop MSBuild is available for sdk tasks.\n    if( -not ($GlobalJson.tools.PSObject.Properties.Name -contains \"vs\" )) {\n      $GlobalJson.tools | Add-Member -Name \"vs\" -Value (ConvertFrom-Json \"{ `\"version`\": `\"16.5`\" }\") -MemberType NoteProperty\n    }\n    if( -not ($GlobalJson.tools.PSObject.Properties.Name -match \"xcopy-msbuild\" )) {\n      $GlobalJson.tools | Add-Member -Name \"xcopy-msbuild\" -Value \"17.12.0\" -MemberType NoteProperty\n    }\n    if ($GlobalJson.tools.\"xcopy-msbuild\".Trim() -ine \"none\") {\n        $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools.\"xcopy-msbuild\" -install $true\n    }\n    if ($xcopyMSBuildToolsFolder -eq $null) {\n      throw 'Unable to get xcopy downloadable version of msbuild'\n    }\n\n    $global:_MSBuildExe = \"$($xcopyMSBuildToolsFolder)\\MSBuild\\Current\\Bin\\MSBuild.exe\"\n  }\n\n  $taskProject = GetSdkTaskProject $task\n  if (!(Test-Path $taskProject)) {\n    Write-PipelineTelemetryError -Category 'Build' -Message \"Unknown task: $task\"\n    ExitWithExitCode 1\n  }\n\n  if ($restore) {\n    Build 'Restore'\n  }\n\n  Build 'Execute'\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Category 'Build' -Message $_\n  ExitWithExitCode 1\n}\n\nExitWithExitCode 0\n"
  },
  {
    "path": "eng/common/sdl/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    <clear />\n    <add key=\"guardian\" value=\"https://securitytools.pkgs.visualstudio.com/_packaging/Guardian/nuget/v3/index.json\" />\n  </packageSources>\n  <packageSourceMapping>\n    <packageSource key=\"guardian\">\n      <package pattern=\"microsoft.guardian.cli\" />\n    </packageSource>\n  </packageSourceMapping>\n  <disabledPackageSources>\n    <clear />\n  </disabledPackageSources>\n</configuration>\n"
  },
  {
    "path": "eng/common/sdl/configure-sdl-tool.ps1",
    "content": "Param(\n  [string] $GuardianCliLocation,\n  [string] $WorkingDirectory,\n  [string] $TargetDirectory,\n  [string] $GdnFolder,\n  # The list of Guardian tools to configure. For each object in the array:\n  # - If the item is a [hashtable], it must contain these entries:\n  #   - Name = The tool name as Guardian knows it.\n  #   - Scenario = (Optional) Scenario-specific name for this configuration entry. It must be unique\n  #     among all tool entries with the same Name.\n  #   - Args = (Optional) Array of Guardian tool configuration args, like '@(\"Target > C:\\temp\")'\n  # - If the item is a [string] $v, it is treated as '@{ Name=\"$v\" }'\n  [object[]] $ToolsList,\n  [string] $GuardianLoggerLevel='Standard',\n  # Optional: Additional params to add to any tool using CredScan.\n  [string[]] $CrScanAdditionalRunConfigParams,\n  # Optional: Additional params to add to any tool using PoliCheck.\n  [string[]] $PoliCheckAdditionalRunConfigParams,\n  # Optional: Additional params to add to any tool using CodeQL/Semmle.\n  [string[]] $CodeQLAdditionalRunConfigParams,\n  # Optional: Additional params to add to any tool using Binskim.\n  [string[]] $BinskimAdditionalRunConfigParams\n)\n\n$ErrorActionPreference = 'Stop'\nSet-StrictMode -Version 2.0\n$disableConfigureToolsetImport = $true\n$global:LASTEXITCODE = 0\n\ntry {\n  # `tools.ps1` checks $ci to perform some actions. Since the SDL\n  # scripts don't necessarily execute in the same agent that run the\n  # build.ps1/sh script this variable isn't automatically set.\n  $ci = $true\n  . $PSScriptRoot\\..\\tools.ps1\n\n  # Normalize tools list: all in [hashtable] form with defined values for each key.\n  $ToolsList = $ToolsList |\n    ForEach-Object {\n      if ($_ -is [string]) {\n        $_ = @{ Name = $_ }\n      }\n\n      if (-not ($_['Scenario'])) { $_.Scenario = \"\" }\n      if (-not ($_['Args'])) { $_.Args = @() }\n      $_\n    }\n  \n  Write-Host \"List of tools to configure:\"\n  $ToolsList | ForEach-Object { $_ | Out-String | Write-Host }\n\n  # We store config files in the r directory of .gdn\n  $gdnConfigPath = Join-Path $GdnFolder 'r'\n  $ValidPath = Test-Path $GuardianCliLocation\n\n  if ($ValidPath -eq $False)\n  {\n    Write-PipelineTelemetryError -Force -Category 'Sdl' -Message \"Invalid Guardian CLI Location.\"\n    ExitWithExitCode 1\n  }\n\n  foreach ($tool in $ToolsList) {\n    # Put together the name and scenario to make a unique key.\n    $toolConfigName = $tool.Name\n    if ($tool.Scenario) {\n      $toolConfigName += \"_\" + $tool.Scenario\n    }\n\n    Write-Host \"=== Configuring $toolConfigName...\"\n\n    $gdnConfigFile = Join-Path $gdnConfigPath \"$toolConfigName-configure.gdnconfig\"\n\n    # For some tools, add default and automatic args.\n    switch -Exact ($tool.Name) {\n      'credscan' {\n        if ($targetDirectory) {\n          $tool.Args += \"`\"TargetDirectory < $TargetDirectory`\"\"\n        }\n        $tool.Args += \"`\"OutputType < pre`\"\"\n        $tool.Args += $CrScanAdditionalRunConfigParams\n      }\n      'policheck' {\n        if ($targetDirectory) {\n          $tool.Args += \"`\"Target < $TargetDirectory`\"\"\n        }\n        $tool.Args += $PoliCheckAdditionalRunConfigParams\n      }\n      {$_ -in 'semmle', 'codeql'} {\n        if ($targetDirectory) {\n          $tool.Args += \"`\"SourceCodeDirectory < $TargetDirectory`\"\"\n        }\n        $tool.Args += $CodeQLAdditionalRunConfigParams\n      }\n      'binskim' {\n        if ($targetDirectory) {\n          # Binskim crashes due to specific PDBs. GitHub issue: https://github.com/microsoft/binskim/issues/924.\n          # We are excluding all `_.pdb` files from the scan.\n          $tool.Args += \"`\"Target < $TargetDirectory\\**;-:file|$TargetDirectory\\**\\_.pdb`\"\"\n        }\n        $tool.Args += $BinskimAdditionalRunConfigParams\n      }\n    }\n\n    # Create variable pointing to the args array directly so we can use splat syntax later.\n    $toolArgs = $tool.Args\n\n    # Configure the tool. If args array is provided or the current tool has some default arguments\n    # defined, add \"--args\" and splat each element on the end. Arg format is \"{Arg id} < {Value}\",\n    # one per parameter. Doc page for \"guardian configure\":\n    # https://dev.azure.com/securitytools/SecurityIntegration/_wiki/wikis/Guardian/1395/configure\n    Exec-BlockVerbosely {\n      & $GuardianCliLocation configure `\n        --working-directory $WorkingDirectory `\n        --tool $tool.Name `\n        --output-path $gdnConfigFile `\n        --logger-level $GuardianLoggerLevel `\n        --noninteractive `\n        --force `\n        $(if ($toolArgs) { \"--args\" }) @toolArgs\n      Exit-IfNZEC \"Sdl\"\n    }\n\n    Write-Host \"Created '$toolConfigName' configuration file: $gdnConfigFile\"\n  }\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/sdl/execute-all-sdl-tools.ps1",
    "content": "Param(\n  [string] $GuardianPackageName,                                                                 # Required: the name of guardian CLI package (not needed if GuardianCliLocation is specified)\n  [string] $NugetPackageDirectory,                                                               # Required: directory where NuGet packages are installed (not needed if GuardianCliLocation is specified)\n  [string] $GuardianCliLocation,                                                                 # Optional: Direct location of Guardian CLI executable if GuardianPackageName & NugetPackageDirectory are not specified\n  [string] $Repository=$env:BUILD_REPOSITORY_NAME,                                               # Required: the name of the repository (e.g. dotnet/arcade)\n  [string] $BranchName=$env:BUILD_SOURCEBRANCH,                                                  # Optional: name of branch or version of gdn settings; defaults to master\n  [string] $SourceDirectory=$env:BUILD_SOURCESDIRECTORY,                                         # Required: the directory where source files are located\n  [string] $ArtifactsDirectory = (Join-Path $env:BUILD_ARTIFACTSTAGINGDIRECTORY ('artifacts')),  # Required: the directory where build artifacts are located\n  [string] $AzureDevOpsAccessToken,                                                              # Required: access token for dnceng; should be provided via KeyVault\n\n  # Optional: list of SDL tools to run on source code. See 'configure-sdl-tool.ps1' for tools list\n  # format.\n  [object[]] $SourceToolsList,\n  # Optional: list of SDL tools to run on built artifacts. See 'configure-sdl-tool.ps1' for tools\n  # list format.\n  [object[]] $ArtifactToolsList,\n  # Optional: list of SDL tools to run without automatically specifying a target directory. See\n  # 'configure-sdl-tool.ps1' for tools list format.\n  [object[]] $CustomToolsList,\n\n  [bool] $TsaPublish=$False,                                                                     # Optional: true will publish results to TSA; only set to true after onboarding to TSA; TSA is the automated framework used to upload test results as bugs.\n  [string] $TsaBranchName=$env:BUILD_SOURCEBRANCH,                                               # Optional: required for TSA publish; defaults to $(Build.SourceBranchName); TSA is the automated framework used to upload test results as bugs.\n  [string] $TsaRepositoryName=$env:BUILD_REPOSITORY_NAME,                                        # Optional: TSA repository name; will be generated automatically if not submitted; TSA is the automated framework used to upload test results as bugs.\n  [string] $BuildNumber=$env:BUILD_BUILDNUMBER,                                                  # Optional: required for TSA publish; defaults to $(Build.BuildNumber)\n  [bool] $UpdateBaseline=$False,                                                                 # Optional: if true, will update the baseline in the repository; should only be run after fixing any issues which need to be fixed\n  [bool] $TsaOnboard=$False,                                                                     # Optional: if true, will onboard the repository to TSA; should only be run once; TSA is the automated framework used to upload test results as bugs.\n  [string] $TsaInstanceUrl,                                                                      # Optional: only needed if TsaOnboard or TsaPublish is true; the instance-url registered with TSA; TSA is the automated framework used to upload test results as bugs.\n  [string] $TsaCodebaseName,                                                                     # Optional: only needed if TsaOnboard or TsaPublish is true; the name of the codebase registered with TSA; TSA is the automated framework used to upload test results as bugs.\n  [string] $TsaProjectName,                                                                      # Optional: only needed if TsaOnboard or TsaPublish is true; the name of the project registered with TSA; TSA is the automated framework used to upload test results as bugs.\n  [string] $TsaNotificationEmail,                                                                # Optional: only needed if TsaOnboard is true; the email(s) which will receive notifications of TSA bug filings (e.g. alias@microsoft.com); TSA is the automated framework used to upload test results as bugs.\n  [string] $TsaCodebaseAdmin,                                                                    # Optional: only needed if TsaOnboard is true; the aliases which are admins of the TSA codebase (e.g. DOMAIN\\alias); TSA is the automated framework used to upload test results as bugs.\n  [string] $TsaBugAreaPath,                                                                      # Optional: only needed if TsaOnboard is true; the area path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs.\n  [string] $TsaIterationPath,                                                                    # Optional: only needed if TsaOnboard is true; the iteration path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs.\n  [string] $GuardianLoggerLevel='Standard',                                                      # Optional: the logger level for the Guardian CLI; options are Trace, Verbose, Standard, Warning, and Error\n  [string[]] $CrScanAdditionalRunConfigParams,                                                   # Optional: Additional Params to custom build a CredScan run config in the format @(\"xyz:abc\",\"sdf:1\")\n  [string[]] $PoliCheckAdditionalRunConfigParams,                                                # Optional: Additional Params to custom build a Policheck run config in the format @(\"xyz:abc\",\"sdf:1\")\n  [string[]] $CodeQLAdditionalRunConfigParams,                                                   # Optional: Additional Params to custom build a Semmle/CodeQL run config in the format @(\"xyz < abc\",\"sdf < 1\")\n  [string[]] $BinskimAdditionalRunConfigParams,                                                  # Optional: Additional Params to custom build a Binskim run config in the format @(\"xyz < abc\",\"sdf < 1\")\n  [bool] $BreakOnFailure=$False                                                                  # Optional: Fail the build if there were errors during the run\n)\n\ntry {\n  $ErrorActionPreference = 'Stop'\n  Set-StrictMode -Version 2.0\n  $disableConfigureToolsetImport = $true\n  $global:LASTEXITCODE = 0\n\n  # `tools.ps1` checks $ci to perform some actions. Since the SDL\n  # scripts don't necessarily execute in the same agent that run the\n  # build.ps1/sh script this variable isn't automatically set.\n  $ci = $true\n  . $PSScriptRoot\\..\\tools.ps1\n\n  #Replace repo names to the format of org/repo\n  if (!($Repository.contains('/'))) {\n    $RepoName = $Repository -replace '(.*?)-(.*)', '$1/$2';\n  }\n  else{\n    $RepoName = $Repository;\n  }\n\n  if ($GuardianPackageName) {\n    $guardianCliLocation = Join-Path $NugetPackageDirectory (Join-Path $GuardianPackageName (Join-Path 'tools' 'guardian.cmd'))\n  } else {\n    $guardianCliLocation = $GuardianCliLocation\n  }\n\n  $workingDirectory = (Split-Path $SourceDirectory -Parent)\n  $ValidPath = Test-Path $guardianCliLocation\n\n  if ($ValidPath -eq $False)\n  {\n    Write-PipelineTelemetryError -Force -Category 'Sdl' -Message 'Invalid Guardian CLI Location.'\n    ExitWithExitCode 1\n  }\n\n  Exec-BlockVerbosely {\n    & $(Join-Path $PSScriptRoot 'init-sdl.ps1') -GuardianCliLocation $guardianCliLocation -Repository $RepoName -BranchName $BranchName -WorkingDirectory $workingDirectory -AzureDevOpsAccessToken $AzureDevOpsAccessToken -GuardianLoggerLevel $GuardianLoggerLevel\n  }\n  $gdnFolder = Join-Path $workingDirectory '.gdn'\n\n  if ($TsaOnboard) {\n    if ($TsaCodebaseName -and $TsaNotificationEmail -and $TsaCodebaseAdmin -and $TsaBugAreaPath) {\n      Exec-BlockVerbosely {\n        & $guardianCliLocation tsa-onboard --codebase-name \"$TsaCodebaseName\" --notification-alias \"$TsaNotificationEmail\" --codebase-admin \"$TsaCodebaseAdmin\" --instance-url \"$TsaInstanceUrl\" --project-name \"$TsaProjectName\" --area-path \"$TsaBugAreaPath\" --iteration-path \"$TsaIterationPath\" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel\n      }\n      if ($LASTEXITCODE -ne 0) {\n        Write-PipelineTelemetryError -Force -Category 'Sdl' -Message \"Guardian tsa-onboard failed with exit code $LASTEXITCODE.\"\n        ExitWithExitCode $LASTEXITCODE\n      }\n    } else {\n      Write-PipelineTelemetryError -Force -Category 'Sdl' -Message 'Could not onboard to TSA -- not all required values ($TsaCodebaseName, $TsaNotificationEmail, $TsaCodebaseAdmin, $TsaBugAreaPath) were specified.'\n      ExitWithExitCode 1\n    }\n  }\n\n  # Configure a list of tools with a default target directory. Populates the \".gdn/r\" directory.\n  function Configure-ToolsList([object[]] $tools, [string] $targetDirectory) {\n    if ($tools -and $tools.Count -gt 0) {\n      Exec-BlockVerbosely {\n        & $(Join-Path $PSScriptRoot 'configure-sdl-tool.ps1') `\n          -GuardianCliLocation $guardianCliLocation `\n          -WorkingDirectory $workingDirectory `\n          -TargetDirectory $targetDirectory `\n          -GdnFolder $gdnFolder `\n          -ToolsList $tools `\n          -AzureDevOpsAccessToken $AzureDevOpsAccessToken `\n          -GuardianLoggerLevel $GuardianLoggerLevel `\n          -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams `\n          -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams `\n          -CodeQLAdditionalRunConfigParams $CodeQLAdditionalRunConfigParams `\n          -BinskimAdditionalRunConfigParams $BinskimAdditionalRunConfigParams\n        if ($BreakOnFailure) {\n          Exit-IfNZEC \"Sdl\"\n        }\n      }\n    }\n  }\n\n  # Configure Artifact and Source tools with default Target directories.\n  Configure-ToolsList $ArtifactToolsList $ArtifactsDirectory\n  Configure-ToolsList $SourceToolsList $SourceDirectory\n  # Configure custom tools with no default Target directory.\n  Configure-ToolsList $CustomToolsList $null\n\n  # At this point, all tools are configured in the \".gdn\" directory. Run them all in a single call.\n  # (If we used \"run\" multiple times, each run would overwrite data from earlier runs.)\n  Exec-BlockVerbosely {\n    & $(Join-Path $PSScriptRoot 'run-sdl.ps1') `\n      -GuardianCliLocation $guardianCliLocation `\n      -WorkingDirectory $SourceDirectory `\n      -UpdateBaseline $UpdateBaseline `\n      -GdnFolder $gdnFolder\n  }\n\n  if ($TsaPublish) {\n    if ($TsaBranchName -and $BuildNumber) {\n      if (-not $TsaRepositoryName) {\n        $TsaRepositoryName = \"$($Repository)-$($BranchName)\"\n      }\n      Exec-BlockVerbosely {\n        & $guardianCliLocation tsa-publish --all-tools --repository-name \"$TsaRepositoryName\" --branch-name \"$TsaBranchName\" --build-number \"$BuildNumber\" --onboard $True --codebase-name \"$TsaCodebaseName\" --notification-alias \"$TsaNotificationEmail\" --codebase-admin \"$TsaCodebaseAdmin\" --instance-url \"$TsaInstanceUrl\" --project-name \"$TsaProjectName\" --area-path \"$TsaBugAreaPath\" --iteration-path \"$TsaIterationPath\" --working-directory $workingDirectory  --logger-level $GuardianLoggerLevel\n      }\n      if ($LASTEXITCODE -ne 0) {\n        Write-PipelineTelemetryError -Force -Category 'Sdl' -Message \"Guardian tsa-publish failed with exit code $LASTEXITCODE.\"\n        ExitWithExitCode $LASTEXITCODE\n      }\n    } else {\n      Write-PipelineTelemetryError -Force -Category 'Sdl' -Message 'Could not publish to TSA -- not all required values ($TsaBranchName, $BuildNumber) were specified.'\n      ExitWithExitCode 1\n    }\n  }\n\n  if ($BreakOnFailure) {\n    Write-Host \"Failing the build in case of breaking results...\"\n    Exec-BlockVerbosely {\n      & $guardianCliLocation break --working-directory $workingDirectory --logger-level $GuardianLoggerLevel\n    }\n  } else {\n    Write-Host \"Letting the build pass even if there were breaking results...\"\n  }\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_\n  exit 1\n}\n"
  },
  {
    "path": "eng/common/sdl/extract-artifact-archives.ps1",
    "content": "# This script looks for each archive file in a directory and extracts it into the target directory.\n# For example, the file \"$InputPath/bin.tar.gz\" extracts to \"$ExtractPath/bin.tar.gz.extracted/**\".\n# Uses the \"tar\" utility added to Windows 10 / Windows 2019 that supports tar.gz and zip.\nparam(\n  # Full path to directory where archives are stored.\n  [Parameter(Mandatory=$true)][string] $InputPath,\n  # Full path to directory to extract archives into. May be the same as $InputPath.\n  [Parameter(Mandatory=$true)][string] $ExtractPath\n)\n\n$ErrorActionPreference = 'Stop'\nSet-StrictMode -Version 2.0\n\n$disableConfigureToolsetImport = $true\n\ntry {\n  # `tools.ps1` checks $ci to perform some actions. Since the SDL\n  # scripts don't necessarily execute in the same agent that run the\n  # build.ps1/sh script this variable isn't automatically set.\n  $ci = $true\n  . $PSScriptRoot\\..\\tools.ps1\n\n  Measure-Command {\n    $jobs = @()\n\n    # Find archive files for non-Windows and Windows builds.\n    $archiveFiles = @(\n      Get-ChildItem (Join-Path $InputPath \"*.tar.gz\")\n      Get-ChildItem (Join-Path $InputPath \"*.zip\")\n    )\n\n    foreach ($targzFile in $archiveFiles) {\n      $jobs += Start-Job -ScriptBlock {\n        $file = $using:targzFile\n        $fileName = [System.IO.Path]::GetFileName($file)\n        $extractDir = Join-Path $using:ExtractPath \"$fileName.extracted\"\n\n        New-Item $extractDir -ItemType Directory -Force | Out-Null\n\n        Write-Host \"Extracting '$file' to '$extractDir'...\"\n\n        # Pipe errors to stdout to prevent PowerShell detecting them and quitting the job early.\n        # This type of quit skips the catch, so we wouldn't be able to tell which file triggered the\n        # error. Save output so it can be stored in the exception string along with context.\n        $output = tar -xf $file -C $extractDir 2>&1\n        # Handle NZEC manually rather than using Exit-IfNZEC: we are in a background job, so we\n        # don't have access to the outer scope.\n        if ($LASTEXITCODE -ne 0) {\n          throw \"Error extracting '$file': non-zero exit code ($LASTEXITCODE). Output: '$output'\"\n        }\n\n        Write-Host \"Extracted to $extractDir\"\n      }\n    }\n\n    Receive-Job $jobs -Wait\n  }\n}\ncatch {\n  Write-Host $_\n  Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/sdl/extract-artifact-packages.ps1",
    "content": "param(\n  [Parameter(Mandatory=$true)][string] $InputPath,              # Full path to directory where artifact packages are stored\n  [Parameter(Mandatory=$true)][string] $ExtractPath            # Full path to directory where the packages will be extracted\n)\n\n$ErrorActionPreference = 'Stop'\nSet-StrictMode -Version 2.0\n\n$disableConfigureToolsetImport = $true\n\nfunction ExtractArtifacts {\n  if (!(Test-Path $InputPath)) {\n    Write-Host \"Input Path does not exist: $InputPath\"\n    ExitWithExitCode 0\n  }\n  $Jobs = @()\n  Get-ChildItem \"$InputPath\\*.nupkg\" |\n    ForEach-Object {\n      $Jobs += Start-Job -ScriptBlock $ExtractPackage -ArgumentList $_.FullName\n    }\n\n  foreach ($Job in $Jobs) {\n    Wait-Job -Id $Job.Id | Receive-Job\n  }\n}\n\ntry {\n  # `tools.ps1` checks $ci to perform some actions. Since the SDL\n  # scripts don't necessarily execute in the same agent that run the\n  # build.ps1/sh script this variable isn't automatically set.\n  $ci = $true\n  . $PSScriptRoot\\..\\tools.ps1\n\n  $ExtractPackage = {\n    param( \n      [string] $PackagePath                                 # Full path to a NuGet package\n    )\n\n    if (!(Test-Path $PackagePath)) {\n      Write-PipelineTelemetryError -Category 'Build' -Message \"Input file does not exist: $PackagePath\"\n      ExitWithExitCode 1\n    }\n\n    $RelevantExtensions = @('.dll', '.exe', '.pdb')\n    Write-Host -NoNewLine 'Extracting ' ([System.IO.Path]::GetFileName($PackagePath)) '...'\n\n    $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath)\n    $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId\n\n    Add-Type -AssemblyName System.IO.Compression.FileSystem\n\n    [System.IO.Directory]::CreateDirectory($ExtractPath);\n\n    try {\n      $zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath)\n  \n      $zip.Entries | \n      Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} |\n        ForEach-Object {\n            $TargetPath = Join-Path -Path $ExtractPath -ChildPath (Split-Path -Path $_.FullName)\n            [System.IO.Directory]::CreateDirectory($TargetPath);\n\n            $TargetFile = Join-Path -Path $ExtractPath -ChildPath $_.FullName\n            [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile)\n          }\n    }\n    catch {\n      Write-Host $_\n      Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_\n      ExitWithExitCode 1\n    }\n    finally {\n      $zip.Dispose() \n    }\n  }\n  Measure-Command { ExtractArtifacts }\n}\ncatch {\n  Write-Host $_\n  Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/sdl/init-sdl.ps1",
    "content": "Param(\n  [string] $GuardianCliLocation,\n  [string] $Repository,\n  [string] $BranchName='master',\n  [string] $WorkingDirectory,\n  [string] $AzureDevOpsAccessToken,\n  [string] $GuardianLoggerLevel='Standard'\n)\n\n$ErrorActionPreference = 'Stop'\nSet-StrictMode -Version 2.0\n$disableConfigureToolsetImport = $true\n$global:LASTEXITCODE = 0\n\n# `tools.ps1` checks $ci to perform some actions. Since the SDL\n# scripts don't necessarily execute in the same agent that run the\n# build.ps1/sh script this variable isn't automatically set.\n$ci = $true\n. $PSScriptRoot\\..\\tools.ps1\n\n# Don't display the console progress UI - it's a huge perf hit\n$ProgressPreference = 'SilentlyContinue'\n\n# Construct basic auth from AzDO access token; construct URI to the repository's gdn folder stored in that repository; construct location of zip file\n$encodedPat = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(\":$AzureDevOpsAccessToken\"))\n$escapedRepository = [Uri]::EscapeDataString(\"/$Repository/$BranchName/.gdn\")\n$uri = \"https://dev.azure.com/dnceng/internal/_apis/git/repositories/sdl-tool-cfg/Items?path=$escapedRepository&versionDescriptor[versionOptions]=0&`$format=zip&api-version=5.0\"\n$zipFile = \"$WorkingDirectory/gdn.zip\"\n\nAdd-Type -AssemblyName System.IO.Compression.FileSystem\n$gdnFolder = (Join-Path $WorkingDirectory '.gdn')\n\ntry {\n  # if the folder does not exist, we'll do a guardian init and push it to the remote repository\n  Write-Host 'Initializing Guardian...'\n  Write-Host \"$GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel\"\n  & $GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel\n  if ($LASTEXITCODE -ne 0) {\n    Write-PipelineTelemetryError -Force -Category 'Build' -Message \"Guardian init failed with exit code $LASTEXITCODE.\"\n    ExitWithExitCode $LASTEXITCODE\n  }\n  # We create the mainbaseline so it can be edited later\n  Write-Host \"$GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline\"\n  & $GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline\n  if ($LASTEXITCODE -ne 0) {\n    Write-PipelineTelemetryError -Force -Category 'Build' -Message \"Guardian baseline failed with exit code $LASTEXITCODE.\"\n    ExitWithExitCode $LASTEXITCODE\n  }\n  ExitWithExitCode 0\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/sdl/packages.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Guardian.Cli\" version=\"0.109.0\"/>\n</packages>\n"
  },
  {
    "path": "eng/common/sdl/run-sdl.ps1",
    "content": "Param(\n  [string] $GuardianCliLocation,\n  [string] $WorkingDirectory,\n  [string] $GdnFolder,\n  [string] $UpdateBaseline,\n  [string] $GuardianLoggerLevel='Standard'\n)\n\n$ErrorActionPreference = 'Stop'\nSet-StrictMode -Version 2.0\n$disableConfigureToolsetImport = $true\n$global:LASTEXITCODE = 0\n\ntry {\n  # `tools.ps1` checks $ci to perform some actions. Since the SDL\n  # scripts don't necessarily execute in the same agent that run the\n  # build.ps1/sh script this variable isn't automatically set.\n  $ci = $true\n  . $PSScriptRoot\\..\\tools.ps1\n\n  # We store config files in the r directory of .gdn\n  $gdnConfigPath = Join-Path $GdnFolder 'r'\n  $ValidPath = Test-Path $GuardianCliLocation\n\n  if ($ValidPath -eq $False)\n  {\n    Write-PipelineTelemetryError -Force -Category 'Sdl' -Message \"Invalid Guardian CLI Location.\"\n    ExitWithExitCode 1\n  }\n\n  $gdnConfigFiles = Get-ChildItem $gdnConfigPath -Recurse -Include '*.gdnconfig'\n  Write-Host \"Discovered Guardian config files:\"\n  $gdnConfigFiles | Out-String | Write-Host\n\n  Exec-BlockVerbosely {\n    & $GuardianCliLocation run `\n      --working-directory $WorkingDirectory `\n      --baseline mainbaseline `\n      --update-baseline $UpdateBaseline `\n      --logger-level $GuardianLoggerLevel `\n      --config @gdnConfigFiles\n    Exit-IfNZEC \"Sdl\"\n  }\n}\ncatch {\n  Write-Host $_.ScriptStackTrace\n  Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/sdl/sdl.ps1",
    "content": "\nfunction Install-Gdn {\n    param(\n        [Parameter(Mandatory=$true)]\n        [string]$Path,\n\n        # If omitted, install the latest version of Guardian, otherwise install that specific version.\n        [string]$Version\n    )\n\n    $ErrorActionPreference = 'Stop'\n    Set-StrictMode -Version 2.0\n    $disableConfigureToolsetImport = $true\n    $global:LASTEXITCODE = 0\n\n    # `tools.ps1` checks $ci to perform some actions. Since the SDL\n    # scripts don't necessarily execute in the same agent that run the\n    # build.ps1/sh script this variable isn't automatically set.\n    $ci = $true\n    . $PSScriptRoot\\..\\tools.ps1\n\n    $argumentList = @(\"install\", \"Microsoft.Guardian.Cli\", \"-Source https://securitytools.pkgs.visualstudio.com/_packaging/Guardian/nuget/v3/index.json\", \"-OutputDirectory $Path\", \"-NonInteractive\", \"-NoCache\")\n\n    if ($Version) {\n        $argumentList += \"-Version $Version\"\n    }\n    \n    Start-Process nuget -Verbose -ArgumentList $argumentList -NoNewWindow -Wait\n\n    $gdnCliPath = Get-ChildItem -Filter guardian.cmd -Recurse -Path $Path\n\n    if (!$gdnCliPath)\n    {\n        Write-PipelineTelemetryError -Category 'Sdl' -Message 'Failure installing Guardian'\n    }\n\n    return $gdnCliPath.FullName\n}"
  },
  {
    "path": "eng/common/sdl/trim-assets-version.ps1",
    "content": "<#\n.SYNOPSIS\nInstall and run the 'Microsoft.DotNet.VersionTools.Cli' tool with the 'trim-artifacts-version' command to trim the version from the NuGet assets file name.\n\n.PARAMETER InputPath\nFull path to directory where artifact packages are stored\n\n.PARAMETER Recursive\nSearch for NuGet packages recursively\n\n#>\n\nParam(\n  [string] $InputPath,\n  [bool] $Recursive = $true\n)\n\n$CliToolName = \"Microsoft.DotNet.VersionTools.Cli\"\n\nfunction Install-VersionTools-Cli {\n  param(\n      [Parameter(Mandatory=$true)][string]$Version\n  )\n\n  Write-Host \"Installing the package '$CliToolName' with a version of '$version' ...\"\n  $feed = \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json\"\n\n  $argumentList = @(\"tool\", \"install\", \"--local\", \"$CliToolName\", \"--add-source $feed\", \"--no-cache\", \"--version $Version\", \"--create-manifest-if-needed\")\n  Start-Process \"$dotnet\" -Verbose -ArgumentList $argumentList -NoNewWindow -Wait\n}\n\n# -------------------------------------------------------------------\n\nif (!(Test-Path $InputPath)) {\n  Write-Host \"Input Path '$InputPath' does not exist\"\n  ExitWithExitCode 1\n}\n\n$ErrorActionPreference = 'Stop'\nSet-StrictMode -Version 2.0\n\n$disableConfigureToolsetImport = $true\n$global:LASTEXITCODE = 0\n\n# `tools.ps1` checks $ci to perform some actions. Since the SDL\n# scripts don't necessarily execute in the same agent that run the\n# build.ps1/sh script this variable isn't automatically set.\n$ci = $true\n. $PSScriptRoot\\..\\tools.ps1\n\ntry {\n  $dotnetRoot = InitializeDotNetCli -install:$true\n  $dotnet = \"$dotnetRoot\\dotnet.exe\"\n\n  $toolsetVersion = Read-ArcadeSdkVersion\n  Install-VersionTools-Cli -Version $toolsetVersion\n\n  $cliToolFound = (& \"$dotnet\" tool list --local | Where-Object {$_.Split(' ')[0] -eq $CliToolName})\n  if ($null -eq $cliToolFound) {\n    Write-PipelineTelemetryError -Force -Category 'Sdl' -Message \"The '$CliToolName' tool is not installed.\"\n    ExitWithExitCode 1\n  }\n\n  Exec-BlockVerbosely {\n    & \"$dotnet\" $CliToolName trim-assets-version `\n      --assets-path $InputPath `\n      --recursive $Recursive\n    Exit-IfNZEC \"Sdl\"\n  }\n}\ncatch {\n  Write-Host $_\n  Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_\n  ExitWithExitCode 1\n}\n"
  },
  {
    "path": "eng/common/template-guidance.md",
    "content": "# Overview\n\nArcade provides templates for public (`/templates`) and 1ES pipeline templates (`/templates-official`) scenarios.  Pipelines which are required to be managed by 1ES pipeline templates should reference `/templates-offical`, all other pipelines may reference `/templates`.\n\n## How to use\n\nBasic guidance is:\n\n- 1ES Pipeline Template or 1ES Microbuild template runs should reference `eng/common/templates-official`. Any internal production-graded pipeline should use these templates.\n\n- All other runs should reference `eng/common/templates`.\n\nSee [azure-pipelines.yml](../../azure-pipelines.yml) (templates-official example) or [azure-pipelines-pr.yml](../../azure-pipelines-pr.yml) (templates example) for examples.\n\n#### The `templateIs1ESManaged` parameter\n\nThe `templateIs1ESManaged` is available on most templates and affects which of the variants is used for nested templates. See [Development Notes](#development-notes) below for more information on the `templateIs1ESManaged1 parameter.\n\n- For templates under `job/`, `jobs/`, `steps`, or `post-build/`, this parameter must be explicitly set.\n\n## Multiple outputs\n\n1ES pipeline templates impose a policy where every publish artifact execution results in additional security scans being injected into your pipeline.  When using `templates-official/jobs/jobs.yml`, Arcade reduces the number of additional security injections by gathering all publishing outputs into the [Build.ArtifactStagingDirectory](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services), and utilizing the [outputParentDirectory](https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/outputs#multiple-outputs) feature of 1ES pipeline templates.  When implementing your pipeline, if you ensure publish artifacts are located in the `$(Build.ArtifactStagingDirectory)`, and utilize the 1ES provided template context, then you can reduce the number of security scans for your pipeline.\n\nExample:\n``` yaml\n# azure-pipelines.yml\nextends:\n  template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate\n  parameters:\n    stages:\n    - stage: build\n      jobs:\n      - template: /eng/common/templates-official/jobs/jobs.yml@self\n        parameters:\n          # 1ES makes use of outputs to reduce security task injection overhead\n          templateContext:\n            outputs:\n            - output: pipelineArtifact\n              displayName: 'Publish logs from source'\n              continueOnError: true\n              condition: always()\n              targetPath: $(Build.ArtifactStagingDirectory)/artifacts/log\n              artifactName: Logs\n          jobs:\n          - job: Windows\n            steps:\n            - script: echo \"friendly neighborhood\" > artifacts/marvel/spiderman.txt\n          # copy build outputs to artifact staging directory for publishing\n          - task: CopyFiles@2\n              displayName: Gather build output\n              inputs:\n                SourceFolder: '$(Build.SourcesDirectory)/artifacts/marvel'\n                Contents: '**'\n                TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/marvel'\n```\n\nNote: Multiple outputs are ONLY applicable to 1ES PT publishing (only usable when referencing `templates-official`).\n\n## Development notes\n\n**Folder / file structure**\n\n``` text\neng\\common\\\n    [templates || templates-official]\\\n        job\\\n            job.yml                          (shim + artifact publishing logic)\n            onelocbuild.yml                  (shim)\n            publish-build-assets.yml         (shim)\n            source-build.yml                 (shim)\n            source-index-stage1.yml          (shim)\n        jobs\\\n            codeql-build.yml                 (shim)\n            jobs.yml                         (shim)\n            source-build.yml                 (shim)\n        post-build\\\n            post-build.yml                   (shim)\n            common-variabls.yml              (shim)\n            setup-maestro-vars.yml           (shim)\n        steps\\\n            publish-build-artifacts.yml      (logic)\n            publish-pipeline-artifacts.yml   (logic)\n            component-governance.yml         (shim)\n            generate-sbom.yml                (shim)\n            publish-logs.yml                 (shim)\n            retain-build.yml                 (shim)\n            send-to-helix.yml                (shim)\n            source-build.yml                 (shim)\n        variables\\\n            pool-providers.yml               (logic + redirect) # templates/variables/pool-providers.yml will redirect to templates-official/variables/pool-providers.yml if you are running in the internal project\n            sdl-variables.yml                (logic)\n    core-templates\\\n        job\\\n            job.yml                          (logic)\n            onelocbuild.yml                  (logic)\n            publish-build-assets.yml         (logic)\n            source-build.yml                 (logic)\n            source-index-stage1.yml          (logic)\n        jobs\\\n            codeql-build.yml                 (logic)\n            jobs.yml                         (logic)\n            source-build.yml                 (logic)\n        post-build\\\n            common-variabls.yml              (logic)\n            post-build.yml                   (logic)\n            setup-maestro-vars.yml           (logic)\n        steps\\\n            component-governance.yml         (logic)\n            generate-sbom.yml                (logic)\n            publish-build-artifacts.yml      (redirect)\n            publish-logs.yml                 (logic)\n            publish-pipeline-artifacts.yml   (redirect)\n            retain-build.yml                 (logic)\n            send-to-helix.yml                (logic)\n            source-build.yml                 (logic)\n        variables\\\n            pool-providers.yml               (redirect)\n```\n\nIn the table above, a file is designated as \"shim\", \"logic\", or \"redirect\".\n\n- shim - represents a yaml file which is an intermediate step between pipeline logic and .Net Core Engineering's templates (`core-templates`) and defines the `is1ESPipeline` parameter value.\n\n- logic - represents actual base template logic.\n\n- redirect- represents a file in `core-templates` which redirects to the \"logic\" file in either `templates` or `templates-official`.\n\nLogic for Arcade's templates live **primarily** in the `core-templates` folder.  The exceptions to the location of the logic files are around artifact publishing, which is handled differently between 1es pipeline templates and standard templates.  `templates` and `templates-official` provide shim entry points which redirect to `core-templates` while also defining the `is1ESPipeline` parameter.  If a shim is referenced in `templates`, then `is1ESPipeline` is set to `false`.  If a shim is referenced in `templates-official`, then `is1ESPipeline` is set to `true`.\n\nWithin `templates` and `templates-official`, the templates at the \"stages\", and \"jobs\" / \"job\" level have been replaced with shims.  Templates at the \"steps\" and \"variables\" level are typically too granular to be replaced with shims and instead persist logic which is directly applicable to either scenario.\n\nWithin `core-templates`, there are a handful of places where logic is dependent on which shim entry point was used.  In those places, we redirect back to the respective logic file in `templates` or `templates-official`.\n"
  },
  {
    "path": "eng/common/templates/job/job.yml",
    "content": "parameters: \n  enablePublishBuildArtifacts: false\n  disableComponentGovernance: ''\n  componentGovernanceIgnoreDirectories: ''\n# Sbom related params\n  enableSbom: true\n  runAsPublic: false\n  PackageVersion: 9.0.0\n  BuildDropPath: '$(Build.SourcesDirectory)/artifacts'\n\njobs:\n- template: /eng/common/core-templates/job/job.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ if and(ne(parameter.key, 'steps'), ne(parameter.key, 'is1ESPipeline')) }}:\n        ${{ parameter.key }}: ${{ parameter.value }}\n\n    steps:\n    - ${{ each step in parameters.steps }}:\n      - ${{ step }}\n\n    componentGovernanceSteps:\n    - template: /eng/common/templates/steps/component-governance.yml\n      parameters:\n        ${{ if eq(parameters.disableComponentGovernance, '') }}:\n          ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}:\n            disableComponentGovernance: false\n          ${{ else }}:\n            disableComponentGovernance: true\n        ${{ else }}:\n          disableComponentGovernance: ${{ parameters.disableComponentGovernance }}\n        componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}\n\n    artifactPublishSteps:\n    - ${{ if ne(parameters.artifacts.publish, '') }}:\n      - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:\n        - template: /eng/common/core-templates/steps/publish-build-artifacts.yml\n          parameters:\n            is1ESPipeline: false\n            args:\n              displayName: Publish pipeline artifacts\n              pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts'\n              publishLocation: Container\n              artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}\n              continueOnError: true\n              condition: always()\n      - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:\n        - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml\n          parameters:\n            is1ESPipeline: false\n            args:\n              targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log'\n              artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }}\n              displayName: 'Publish logs'\n              continueOnError: true\n              condition: always()\n              sbomEnabled: false  # we don't need SBOM for logs\n\n    - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}:\n      - template: /eng/common/core-templates/steps/publish-build-artifacts.yml\n        parameters:\n          is1ESPipeline: false\n          args:\n            displayName: Publish Logs\n            pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'\n            publishLocation: Container\n            artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}\n            continueOnError: true\n            condition: always()\n\n    - ${{ if eq(parameters.enableBuildRetry, 'true') }}:\n      - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml\n        parameters:\n          is1ESPipeline: false\n          args:\n            targetPath: '$(Build.SourcesDirectory)\\eng\\common\\BuildConfiguration'\n            artifactName: 'BuildConfiguration'\n            displayName: 'Publish build retry configuration'\n            continueOnError: true\n            sbomEnabled: false  # we don't need SBOM for BuildConfiguration\n"
  },
  {
    "path": "eng/common/templates/job/onelocbuild.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/job/onelocbuild.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/job/publish-build-assets.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/job/publish-build-assets.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/job/source-build.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/job/source-build.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/job/source-index-stage1.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/job/source-index-stage1.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/jobs/codeql-build.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/jobs/codeql-build.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/jobs/jobs.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/jobs/jobs.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/jobs/source-build.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/jobs/source-build.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates/post-build/common-variables.yml",
    "content": "variables:\n- template: /eng/common/core-templates/post-build/common-variables.yml\n  parameters:\n    # Specifies whether to use 1ES\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates/post-build/post-build.yml",
    "content": "stages:\n- template: /eng/common/core-templates/post-build/post-build.yml\n  parameters:\n    # Specifies whether to use 1ES\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates/post-build/setup-maestro-vars.yml",
    "content": "steps:\n- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml\n  parameters:\n    # Specifies whether to use 1ES\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates/steps/component-governance.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/component-governance.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/steps/enable-internal-runtimes.yml",
    "content": "# Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'\n# variable with the base64-encoded SAS token, by default\n\nsteps:\n- template: /eng/common/core-templates/steps/enable-internal-runtimes.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/steps/enable-internal-sources.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/enable-internal-sources.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates/steps/generate-sbom.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/generate-sbom.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/steps/get-delegation-sas.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/get-delegation-sas.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/steps/get-federated-access-token.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/get-federated-access-token.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates/steps/publish-build-artifacts.yml",
    "content": "parameters:\n- name: is1ESPipeline\n  type: boolean\n  default: false\n\n- name: displayName\n  type: string\n  default: 'Publish to Build Artifact'\n\n- name: condition\n  type: string\n  default: succeeded()\n\n- name: artifactName\n  type: string\n\n- name: pathToPublish\n  type: string\n\n- name: continueOnError\n  type: boolean\n  default: false\n\n- name: publishLocation\n  type: string\n  default: 'Container'\n\nsteps:\n- ${{ if eq(parameters.is1ESPipeline, true) }}:\n  - 'eng/common/templates cannot be referenced from a 1ES managed template': error\n- task: PublishBuildArtifacts@1\n  displayName: ${{ parameters.displayName }}\n  condition: ${{ parameters.condition }}\n  ${{ if parameters.continueOnError }}:\n    continueOnError: ${{ parameters.continueOnError }}\n  inputs:\n    PublishLocation: ${{ parameters.publishLocation }}  \n    PathtoPublish: ${{ parameters.pathToPublish }}\n    ${{ if parameters.artifactName }}:\n      ArtifactName: ${{ parameters.artifactName }}"
  },
  {
    "path": "eng/common/templates/steps/publish-logs.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/publish-logs.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/steps/publish-pipeline-artifacts.yml",
    "content": "parameters:\n- name: is1ESPipeline\n  type: boolean\n  default: false\n\n- name: args\n  type: object\n  default: {}\n\nsteps:\n- ${{ if eq(parameters.is1ESPipeline, true) }}:\n  - 'eng/common/templates cannot be referenced from a 1ES managed template': error\n- task: PublishPipelineArtifact@1\n  displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }}\n  ${{ if parameters.args.condition }}:\n    condition: ${{ parameters.args.condition }}\n  ${{ else }}:\n    condition: succeeded()\n  ${{ if parameters.args.continueOnError }}:\n    continueOnError: ${{ parameters.args.continueOnError }}\n  inputs:\n    targetPath: ${{ parameters.args.targetPath }}\n    ${{ if parameters.args.artifactName }}:\n      artifactName: ${{ parameters.args.artifactName }}\n    ${{ if parameters.args.publishLocation }}:\n      publishLocation: ${{ parameters.args.publishLocation }}\n    ${{ if parameters.args.fileSharePath }}:\n      fileSharePath: ${{ parameters.args.fileSharePath }}\n    ${{ if parameters.args.Parallel }}:\n      parallel: ${{ parameters.args.Parallel }}\n    ${{ if parameters.args.parallelCount }}:\n      parallelCount: ${{ parameters.args.parallelCount }}\n    ${{ if parameters.args.properties }}:\n      properties: ${{ parameters.args.properties }}"
  },
  {
    "path": "eng/common/templates/steps/retain-build.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/retain-build.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/steps/send-to-helix.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/send-to-helix.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/steps/source-build.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/source-build.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/steps/source-index-stage1-publish.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml\n  parameters:\n    is1ESPipeline: false\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates/variables/pool-providers.yml",
    "content": "# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool,\n# otherwise it should go into the \"normal\" pools. This separates out the queueing and billing of released branches.\n\n# Motivation:\n#   Once a given branch of a repository's output has been officially \"shipped\" once, it is then considered to be COGS\n#   (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing\n#   (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS.\n#   Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services\n#   team needs to move resources around and create new and potentially differently-named pools. Using this template\n#   file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming.\n\n# How to use:\n#  This yaml assumes your shipped product branches use the naming convention \"release/...\" (which many do).\n#  If we find alternate naming conventions in broad usage it can be added to the condition below.\n#\n#  First, import the template in an arcade-ified repo to pick up the variables, e.g.:\n#\n#  variables:\n#  - template: /eng/common/templates/variables/pool-providers.yml\n#\n#  ... then anywhere specifying the pool provider use the runtime variables,\n#      $(DncEngInternalBuildPool) and $  (DncEngPublicBuildPool), e.g.:\n#\n#        pool:\n#           name: $(DncEngInternalBuildPool)\n#           demands: ImageOverride -equals windows.vs2019.amd64\nvariables:\n  - ${{ if eq(variables['System.TeamProject'], 'internal') }}:\n    - template: /eng/common/templates-official/variables/pool-providers.yml\n  - ${{ else }}:\n    # Coalesce the target and source branches so we know when a PR targets a release branch\n    # If these variables are somehow missing, fall back to main (tends to have more capacity)\n\n    # Any new -Svc alternative pools should have variables added here to allow for splitting work\n    - name: DncEngPublicBuildPool\n      value: $[\n          replace(\n            replace(\n              eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'),\n              True,\n              'NetCore-Svc-Public'\n            ),\n            False,\n            'NetCore-Public'\n          )\n        ]\n\n    - name: DncEngInternalBuildPool\n      value: $[\n          replace(\n            replace(\n              eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'),\n              True,\n              'NetCore1ESPool-Svc-Internal'\n            ),\n            False,\n            'NetCore1ESPool-Internal'\n          )\n        ]\n"
  },
  {
    "path": "eng/common/templates-official/job/job.yml",
    "content": "parameters:\n# Sbom related params\n  enableSbom: true\n  runAsPublic: false\n  PackageVersion: 9.0.0\n  BuildDropPath: '$(Build.SourcesDirectory)/artifacts'\n\njobs:\n- template: /eng/common/core-templates/job/job.yml\n  parameters:\n    is1ESPipeline: true\n\n    componentGovernanceSteps:\n    - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:\n      - template: /eng/common/templates/steps/generate-sbom.yml\n        parameters:\n          PackageVersion: ${{ parameters.packageVersion }}\n          BuildDropPath: ${{ parameters.buildDropPath }}\n          publishArtifacts: false\n\n    # publish artifacts\n    # for 1ES managed templates, use the templateContext.output to handle multiple outputs.\n    templateContext:\n      outputParentDirectory: $(Build.ArtifactStagingDirectory)\n      outputs:\n      - ${{ if ne(parameters.artifacts.publish, '') }}:\n        - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:\n          - output: buildArtifacts\n            displayName: Publish pipeline artifacts\n            PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'\n            ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}\n            condition: always()\n            continueOnError: true\n        - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:\n          - output: pipelineArtifact\n            targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log'\n            artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)_Attempt$(System.JobAttempt)') }}\n            displayName: 'Publish logs'\n            continueOnError: true\n            condition: always()\n            sbomEnabled: false  # we don't need SBOM for logs\n\n      - ${{ if eq(parameters.enablePublishBuildArtifacts, true) }}:\n        - output: buildArtifacts\n          displayName: Publish Logs\n          PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'\n          publishLocation: Container\n          ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}\n          continueOnError: true\n          condition: always()\n          sbomEnabled: false  # we don't need SBOM for logs\n\n      - ${{ if eq(parameters.enableBuildRetry, 'true') }}:\n        - output: pipelineArtifact\n          targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/eng/common/BuildConfiguration'\n          artifactName: 'BuildConfiguration'\n          displayName: 'Publish build retry configuration'\n          continueOnError: true\n          sbomEnabled: false  # we don't need SBOM for BuildConfiguration\n\n      - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:\n        - output: pipelineArtifact\n          displayName: Publish SBOM manifest\n          continueOnError: true\n          targetPath: $(Build.ArtifactStagingDirectory)/sbom\n          artifactName: $(ARTIFACT_NAME)\n\n      # add any outputs provided via root yaml\n      - ${{ if ne(parameters.templateContext.outputs, '') }}:\n        - ${{ each output in parameters.templateContext.outputs }}:\n          - ${{ output }}\n      \n      # add any remaining templateContext properties\n      ${{ each context in parameters.templateContext }}:\n        ${{ if and(ne(context.key, 'outputParentDirectory'), ne(context.key, 'outputs')) }}:\n          ${{ context.key }}: ${{ context.value }}\n\n    ${{ each parameter in parameters }}:\n      ${{ if and(ne(parameter.key, 'templateContext'), ne(parameter.key, 'is1ESPipeline')) }}:\n        ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/job/onelocbuild.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/job/onelocbuild.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/job/publish-build-assets.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/job/publish-build-assets.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/job/source-build.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/job/source-build.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/job/source-index-stage1.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/job/source-index-stage1.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/jobs/codeql-build.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/jobs/codeql-build.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/jobs/jobs.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/jobs/jobs.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/jobs/source-build.yml",
    "content": "jobs:\n- template: /eng/common/core-templates/jobs/source-build.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates-official/post-build/common-variables.yml",
    "content": "variables:\n- template: /eng/common/core-templates/post-build/common-variables.yml\n  parameters:\n    # Specifies whether to use 1ES\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates-official/post-build/post-build.yml",
    "content": "stages:\n- template: /eng/common/core-templates/post-build/post-build.yml\n  parameters:\n    # Specifies whether to use 1ES\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/post-build/setup-maestro-vars.yml",
    "content": "steps:\n- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml\n  parameters:\n    # Specifies whether to use 1ES\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates-official/steps/component-governance.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/component-governance.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/steps/enable-internal-runtimes.yml",
    "content": "# Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'\n# variable with the base64-encoded SAS token, by default\nsteps:\n- template: /eng/common/core-templates/steps/enable-internal-runtimes.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/steps/enable-internal-sources.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/enable-internal-sources.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates-official/steps/generate-sbom.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/generate-sbom.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/steps/get-delegation-sas.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/get-delegation-sas.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/steps/get-federated-access-token.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/get-federated-access-token.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}"
  },
  {
    "path": "eng/common/templates-official/steps/publish-build-artifacts.yml",
    "content": "parameters:\n- name: displayName\n  type: string\n  default: 'Publish to Build Artifact'\n\n- name: condition\n  type: string\n  default: succeeded()\n\n- name: artifactName\n  type: string\n\n- name: pathToPublish\n  type: string\n\n- name: continueOnError\n  type: boolean\n  default: false\n\n- name: publishLocation\n  type: string\n  default: 'Container'\n\n- name: is1ESPipeline\n  type: boolean\n  default: true\n  \nsteps:\n- ${{ if ne(parameters.is1ESPipeline, true) }}:\n  - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error\n- task: 1ES.PublishBuildArtifacts@1\n  displayName: ${{ parameters.displayName }}\n  condition: ${{ parameters.condition }}\n  ${{ if parameters.continueOnError }}:\n    continueOnError: ${{ parameters.continueOnError }}\n  inputs:\n    PublishLocation: ${{ parameters.publishLocation }}\n    PathtoPublish: ${{ parameters.pathToPublish }}\n    ${{ if parameters.artifactName }}:\n      ArtifactName: ${{ parameters.artifactName }}\n      \n"
  },
  {
    "path": "eng/common/templates-official/steps/publish-logs.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/publish-logs.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/steps/publish-pipeline-artifacts.yml",
    "content": "parameters:\n- name: is1ESPipeline\n  type: boolean\n  default: true\n\n- name: args\n  type: object\n  default: {}\n\nsteps:\n- ${{ if ne(parameters.is1ESPipeline, true) }}:\n  - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error\n- task: 1ES.PublishPipelineArtifact@1\n  displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }}\n  ${{ if parameters.args.condition }}:\n    condition: ${{ parameters.args.condition }}\n  ${{ else }}:\n    condition: succeeded()\n  ${{ if parameters.args.continueOnError }}:\n    continueOnError: ${{ parameters.args.continueOnError }}\n  inputs:\n    targetPath: ${{ parameters.args.targetPath }}\n    ${{ if parameters.args.artifactName }}:\n      artifactName: ${{ parameters.args.artifactName }}\n    ${{ if parameters.args.properties }}:\n      properties: ${{ parameters.args.properties }}\n    ${{ if parameters.args.sbomEnabled }}:\n      sbomEnabled: ${{ parameters.args.sbomEnabled }}\n"
  },
  {
    "path": "eng/common/templates-official/steps/retain-build.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/retain-build.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/steps/send-to-helix.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/send-to-helix.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/steps/source-build.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/source-build.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/steps/source-index-stage1-publish.yml",
    "content": "steps:\n- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml\n  parameters:\n    is1ESPipeline: true\n\n    ${{ each parameter in parameters }}:\n      ${{ parameter.key }}: ${{ parameter.value }}\n"
  },
  {
    "path": "eng/common/templates-official/variables/pool-providers.yml",
    "content": "# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, \n# otherwise it should go into the \"normal\" pools. This separates out the queueing and billing of released branches.\n\n# Motivation: \n#   Once a given branch of a repository's output has been officially \"shipped\" once, it is then considered to be COGS\n#   (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing\n#   (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS.\n#   Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services \n#   team needs to move resources around and create new and potentially differently-named pools. Using this template \n#   file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming.\n\n# How to use: \n#  This yaml assumes your shipped product branches use the naming convention \"release/...\" (which many do).\n#  If we find alternate naming conventions in broad usage it can be added to the condition below.\n#\n#  First, import the template in an arcade-ified repo to pick up the variables, e.g.:\n#\n#  variables:\n#  - template: /eng/common/templates-official/variables/pool-providers.yml\n#\n#  ... then anywhere specifying the pool provider use the runtime variables,\n#      $(DncEngInternalBuildPool)\n#\n#        pool:\n#           name: $(DncEngInternalBuildPool)\n#           image: 1es-windows-2022\n\nvariables:\n  # Coalesce the target and source branches so we know when a PR targets a release branch\n  # If these variables are somehow missing, fall back to main (tends to have more capacity)\n\n  # Any new -Svc alternative pools should have variables added here to allow for splitting work\n\n  - name: DncEngInternalBuildPool\n    value: $[\n        replace(\n          replace(\n            eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'),\n            True,\n            'NetCore1ESPool-Svc-Internal'\n          ),\n          False,\n          'NetCore1ESPool-Internal'\n        )\n      ]"
  },
  {
    "path": "eng/common/templates-official/variables/sdl-variables.yml",
    "content": "variables:\n# The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in\n# sync with the packages.config file.\n- name: DefaultGuardianVersion\n  value: 0.109.0\n- name: GuardianPackagesConfigFile\n  value: $(Build.SourcesDirectory)\\eng\\common\\sdl\\packages.config"
  },
  {
    "path": "eng/common/tools.ps1",
    "content": "# Initialize variables if they aren't already defined.\n# These may be defined as parameters of the importing script, or set after importing this script.\n\n# CI mode - set to true on CI server for PR validation build or official build.\n[bool]$ci = if (Test-Path variable:ci) { $ci } else { $false }\n\n# Build configuration. Common values include 'Debug' and 'Release', but the repository may use other names.\n[string]$configuration = if (Test-Path variable:configuration) { $configuration } else { 'Debug' }\n\n# Set to true to opt out of outputting binary log while running in CI\n[bool]$excludeCIBinarylog = if (Test-Path variable:excludeCIBinarylog) { $excludeCIBinarylog } else { $false }\n\n# Set to true to output binary log from msbuild. Note that emitting binary log slows down the build.\n[bool]$binaryLog = if (Test-Path variable:binaryLog) { $binaryLog } else { $ci -and !$excludeCIBinarylog }\n\n# Set to true to use the pipelines logger which will enable Azure logging output.\n# https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md\n# This flag is meant as a temporary opt-opt for the feature while validate it across\n# our consumers. It will be deleted in the future.\n[bool]$pipelinesLog = if (Test-Path variable:pipelinesLog) { $pipelinesLog } else { $ci }\n\n# Turns on machine preparation/clean up code that changes the machine state (e.g. kills build processes).\n[bool]$prepareMachine = if (Test-Path variable:prepareMachine) { $prepareMachine } else { $false }\n\n# True to restore toolsets and dependencies.\n[bool]$restore = if (Test-Path variable:restore) { $restore } else { $true }\n\n# Adjusts msbuild verbosity level.\n[string]$verbosity = if (Test-Path variable:verbosity) { $verbosity } else { 'minimal' }\n\n# Set to true to reuse msbuild nodes. Recommended to not reuse on CI.\n[bool]$nodeReuse = if (Test-Path variable:nodeReuse) { $nodeReuse } else { !$ci }\n\n# Configures warning treatment in msbuild.\n[bool]$warnAsError = if (Test-Path variable:warnAsError) { $warnAsError } else { $true }\n\n# Specifies which msbuild engine to use for build: 'vs', 'dotnet' or unspecified (determined based on presence of tools.vs in global.json).\n[string]$msbuildEngine = if (Test-Path variable:msbuildEngine) { $msbuildEngine } else { $null }\n\n# True to attempt using .NET Core already that meets requirements specified in global.json\n# installed on the machine instead of downloading one.\n[bool]$useInstalledDotNetCli = if (Test-Path variable:useInstalledDotNetCli) { $useInstalledDotNetCli } else { $true }\n\n# Enable repos to use a particular version of the on-line dotnet-install scripts.\n#    default URL: https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.ps1\n[string]$dotnetInstallScriptVersion = if (Test-Path variable:dotnetInstallScriptVersion) { $dotnetInstallScriptVersion } else { 'v1' }\n\n# True to use global NuGet cache instead of restoring packages to repository-local directory.\n[bool]$useGlobalNuGetCache = if (Test-Path variable:useGlobalNuGetCache) { $useGlobalNuGetCache } else { !$ci }\n\n# True to exclude prerelease versions Visual Studio during build\n[bool]$excludePrereleaseVS = if (Test-Path variable:excludePrereleaseVS) { $excludePrereleaseVS } else { $false }\n\n# An array of names of processes to stop on script exit if prepareMachine is true.\n$processesToStopOnExit = if (Test-Path variable:processesToStopOnExit) { $processesToStopOnExit } else { @('msbuild', 'dotnet', 'vbcscompiler') }\n\n$disableConfigureToolsetImport = if (Test-Path variable:disableConfigureToolsetImport) { $disableConfigureToolsetImport } else { $null }\n\nset-strictmode -version 2.0\n$ErrorActionPreference = 'Stop'\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n# If specifies, provides an alternate path for getting .NET Core SDKs and Runtimes. This script will still try public sources first.\n[string]$runtimeSourceFeed = if (Test-Path variable:runtimeSourceFeed) { $runtimeSourceFeed } else { $null }\n# Base-64 encoded SAS token that has permission to storage container described by $runtimeSourceFeed\n[string]$runtimeSourceFeedKey = if (Test-Path variable:runtimeSourceFeedKey) { $runtimeSourceFeedKey } else { $null }\n\n# True if the build is a product build\n[bool]$productBuild = if (Test-Path variable:productBuild) { $productBuild } else { $false }\n\n[String[]]$properties = if (Test-Path variable:properties) { $properties } else { @() }\n\nfunction Create-Directory ([string[]] $path) {\n    New-Item -Path $path -Force -ItemType 'Directory' | Out-Null\n}\n\nfunction Unzip([string]$zipfile, [string]$outpath) {\n  Add-Type -AssemblyName System.IO.Compression.FileSystem\n  [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)\n}\n\n# This will exec a process using the console and return it's exit code.\n# This will not throw when the process fails.\n# Returns process exit code.\nfunction Exec-Process([string]$command, [string]$commandArgs) {\n  $startInfo = New-Object System.Diagnostics.ProcessStartInfo\n  $startInfo.FileName = $command\n  $startInfo.Arguments = $commandArgs\n  $startInfo.UseShellExecute = $false\n  $startInfo.WorkingDirectory = Get-Location\n\n  $process = New-Object System.Diagnostics.Process\n  $process.StartInfo = $startInfo\n  $process.Start() | Out-Null\n\n  $finished = $false\n  try {\n    while (-not $process.WaitForExit(100)) {\n      # Non-blocking loop done to allow ctr-c interrupts\n    }\n\n    $finished = $true\n    return $global:LASTEXITCODE = $process.ExitCode\n  }\n  finally {\n    # If we didn't finish then an error occurred or the user hit ctrl-c.  Either\n    # way kill the process\n    if (-not $finished) {\n      $process.Kill()\n    }\n  }\n}\n\n# Take the given block, print it, print what the block probably references from the current set of\n# variables using low-effort string matching, then run the block.\n#\n# This is intended to replace the pattern of manually copy-pasting a command, wrapping it in quotes,\n# and printing it using \"Write-Host\". The copy-paste method is more readable in build logs, but less\n# maintainable and less reliable. It is easy to make a mistake and modify the command without\n# properly updating the \"Write-Host\" line, resulting in misleading build logs. The probability of\n# this mistake makes the pattern hard to trust when it shows up in build logs. Finding the bug in\n# existing source code can also be difficult, because the strings are not aligned to each other and\n# the line may be 300+ columns long.\n#\n# By removing the need to maintain two copies of the command, Exec-BlockVerbosely avoids the issues.\n#\n# In Bash (or any posix-like shell), \"set -x\" prints usable verbose output automatically.\n# \"Set-PSDebug\" appears to be similar at first glance, but unfortunately, it isn't very useful: it\n# doesn't print any info about the variables being used by the command, which is normally the\n# interesting part to diagnose.\nfunction Exec-BlockVerbosely([scriptblock] $block) {\n  Write-Host \"--- Running script block:\"\n  $blockString = $block.ToString().Trim()\n  Write-Host $blockString\n\n  Write-Host \"--- List of variables that might be used:\"\n  # For each variable x in the environment, check the block for a reference to x via simple \"$x\" or\n  # \"@x\" syntax. This doesn't detect other ways to reference variables (\"${x}\" nor \"$variable:x\",\n  # among others). It only catches what this function was originally written for: simple\n  # command-line commands.\n  $variableTable = Get-Variable |\n    Where-Object {\n      $blockString.Contains(\"`$$($_.Name)\") -or $blockString.Contains(\"@$($_.Name)\")\n    } |\n    Format-Table -AutoSize -HideTableHeaders -Wrap |\n    Out-String\n  Write-Host $variableTable.Trim()\n\n  Write-Host \"--- Executing:\"\n  & $block\n  Write-Host \"--- Done running script block!\"\n}\n\n# createSdkLocationFile parameter enables a file being generated under the toolset directory\n# which writes the sdk's location into. This is only necessary for cmd --> powershell invocations\n# as dot sourcing isn't possible.\nfunction InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) {\n  if (Test-Path variable:global:_DotNetInstallDir) {\n    return $global:_DotNetInstallDir\n  }\n\n  # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism\n  $env:DOTNET_MULTILEVEL_LOOKUP=0\n\n  # Disable first run since we do not need all ASP.NET packages restored.\n  $env:DOTNET_NOLOGO=1\n\n  # Disable telemetry on CI.\n  if ($ci) {\n    $env:DOTNET_CLI_TELEMETRY_OPTOUT=1\n  }\n\n  # Find the first path on %PATH% that contains the dotnet.exe\n  if ($useInstalledDotNetCli -and (-not $globalJsonHasRuntimes) -and ($env:DOTNET_INSTALL_DIR -eq $null)) {\n    $dotnetExecutable = GetExecutableFileName 'dotnet'\n    $dotnetCmd = Get-Command $dotnetExecutable -ErrorAction SilentlyContinue\n\n    if ($dotnetCmd -ne $null) {\n      $env:DOTNET_INSTALL_DIR = Split-Path $dotnetCmd.Path -Parent\n    }\n  }\n\n  $dotnetSdkVersion = $GlobalJson.tools.dotnet\n\n  # Use dotnet installation specified in DOTNET_INSTALL_DIR if it contains the required SDK version,\n  # otherwise install the dotnet CLI and SDK to repo local .dotnet directory to avoid potential permission issues.\n  if ((-not $globalJsonHasRuntimes) -and (-not [string]::IsNullOrEmpty($env:DOTNET_INSTALL_DIR)) -and (Test-Path(Join-Path $env:DOTNET_INSTALL_DIR \"sdk\\$dotnetSdkVersion\"))) {\n    $dotnetRoot = $env:DOTNET_INSTALL_DIR\n  } else {\n    $dotnetRoot = Join-Path $RepoRoot '.dotnet'\n\n    if (-not (Test-Path(Join-Path $dotnetRoot \"sdk\\$dotnetSdkVersion\"))) {\n      if ($install) {\n        InstallDotNetSdk $dotnetRoot $dotnetSdkVersion\n      } else {\n        Write-PipelineTelemetryError -Category 'InitializeToolset' -Message \"Unable to find dotnet with SDK version '$dotnetSdkVersion'\"\n        ExitWithExitCode 1\n      }\n    }\n\n    $env:DOTNET_INSTALL_DIR = $dotnetRoot\n  }\n\n  # Creates a temporary file under the toolset dir.\n  # The following code block is protecting against concurrent access so that this function can\n  # be called in parallel.\n  if ($createSdkLocationFile) {\n    do {\n      $sdkCacheFileTemp = Join-Path $ToolsetDir $([System.IO.Path]::GetRandomFileName())\n    }\n    until (!(Test-Path $sdkCacheFileTemp))\n    Set-Content -Path $sdkCacheFileTemp -Value $dotnetRoot\n\n    try {\n      Move-Item -Force $sdkCacheFileTemp (Join-Path $ToolsetDir 'sdk.txt')\n    } catch {\n      # Somebody beat us\n      Remove-Item -Path $sdkCacheFileTemp\n    }\n  }\n\n  # Add dotnet to PATH. This prevents any bare invocation of dotnet in custom\n  # build steps from using anything other than what we've downloaded.\n  # It also ensures that VS msbuild will use the downloaded sdk targets.\n  $env:PATH = \"$dotnetRoot;$env:PATH\"\n\n  # Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build\n  Write-PipelinePrependPath -Path $dotnetRoot\n\n  Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0'\n  Write-PipelineSetVariable -Name 'DOTNET_NOLOGO' -Value '1'\n\n  return $global:_DotNetInstallDir = $dotnetRoot\n}\n\nfunction Retry($downloadBlock, $maxRetries = 5) {\n  $retries = 1\n\n  while($true) {\n    try {\n      & $downloadBlock\n      break\n    }\n    catch {\n      Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_\n    }\n\n    if (++$retries -le $maxRetries) {\n      $delayInSeconds = [math]::Pow(2, $retries) - 1 # Exponential backoff\n      Write-Host \"Retrying. Waiting for $delayInSeconds seconds before next attempt ($retries of $maxRetries).\"\n      Start-Sleep -Seconds $delayInSeconds\n    }\n    else {\n      Write-PipelineTelemetryError -Category 'InitializeToolset' -Message \"Unable to download file in $maxRetries attempts.\"\n      break\n    }\n  }\n}\n\nfunction GetDotNetInstallScript([string] $dotnetRoot) {\n  $installScript = Join-Path $dotnetRoot 'dotnet-install.ps1'\n  if (!(Test-Path $installScript)) {\n    Create-Directory $dotnetRoot\n    $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit\n    $uri = \"https://dotnet.microsoft.com/download/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.ps1\"\n\n    Retry({\n      Write-Host \"GET $uri\"\n      Invoke-WebRequest $uri -OutFile $installScript\n    })\n  }\n\n  return $installScript\n}\n\nfunction InstallDotNetSdk([string] $dotnetRoot, [string] $version, [string] $architecture = '', [switch] $noPath) {\n  InstallDotNet $dotnetRoot $version $architecture '' $false $runtimeSourceFeed $runtimeSourceFeedKey -noPath:$noPath\n}\n\nfunction InstallDotNet([string] $dotnetRoot,\n  [string] $version,\n  [string] $architecture = '',\n  [string] $runtime = '',\n  [bool] $skipNonVersionedFiles = $false,\n  [string] $runtimeSourceFeed = '',\n  [string] $runtimeSourceFeedKey = '',\n  [switch] $noPath) {\n\n  $dotnetVersionLabel = \"'sdk v$version'\"\n\n  if ($runtime -ne '' -and $runtime -ne 'sdk') {\n    $runtimePath = $dotnetRoot\n    $runtimePath = $runtimePath + \"\\shared\"\n    if ($runtime -eq \"dotnet\") { $runtimePath = $runtimePath + \"\\Microsoft.NETCore.App\" }\n    if ($runtime -eq \"aspnetcore\") { $runtimePath = $runtimePath + \"\\Microsoft.AspNetCore.App\" }\n    if ($runtime -eq \"windowsdesktop\") { $runtimePath = $runtimePath + \"\\Microsoft.WindowsDesktop.App\" }\n    $runtimePath = $runtimePath + \"\\\" + $version\n  \n    $dotnetVersionLabel = \"runtime toolset '$runtime/$architecture v$version'\"\n\n    if (Test-Path $runtimePath) {\n      Write-Host \"  Runtime toolset '$runtime/$architecture v$version' already installed.\"\n      $installSuccess = $true\n      Exit\n    }\n  }\n\n  $installScript = GetDotNetInstallScript $dotnetRoot\n  $installParameters = @{\n    Version = $version\n    InstallDir = $dotnetRoot\n  }\n\n  if ($architecture) { $installParameters.Architecture = $architecture }\n  if ($runtime) { $installParameters.Runtime = $runtime }\n  if ($skipNonVersionedFiles) { $installParameters.SkipNonVersionedFiles = $skipNonVersionedFiles }\n  if ($noPath) { $installParameters.NoPath = $True }\n\n  $variations = @()\n  $variations += @($installParameters)\n\n  $dotnetBuilds = $installParameters.Clone()\n  $dotnetbuilds.AzureFeed = \"https://ci.dot.net/public\"\n  $variations += @($dotnetBuilds)\n\n  if ($runtimeSourceFeed) {\n    $runtimeSource = $installParameters.Clone()\n    $runtimeSource.AzureFeed = $runtimeSourceFeed\n    if ($runtimeSourceFeedKey) {\n      $decodedBytes = [System.Convert]::FromBase64String($runtimeSourceFeedKey)\n      $decodedString = [System.Text.Encoding]::UTF8.GetString($decodedBytes)\n      $runtimeSource.FeedCredential = $decodedString\n    }\n    $variations += @($runtimeSource)\n  }\n\n  $installSuccess = $false\n  foreach ($variation in $variations) {\n    if ($variation | Get-Member AzureFeed) {\n      $location = $variation.AzureFeed\n    } else {\n      $location = \"public location\";\n    }\n    Write-Host \"  Attempting to install $dotnetVersionLabel from $location.\"\n    try {\n      & $installScript @variation\n      $installSuccess = $true\n      break\n    }\n    catch {\n      Write-Host \"  Failed to install $dotnetVersionLabel from $location.\"\n    }\n  }\n  if (-not $installSuccess) {\n    Write-PipelineTelemetryError -Category 'InitializeToolset' -Message \"Failed to install $dotnetVersionLabel from any of the specified locations.\"\n    ExitWithExitCode 1\n  }\n}\n\n#\n# Locates Visual Studio MSBuild installation.\n# The preference order for MSBuild to use is as follows:\n#\n#   1. MSBuild from an active VS command prompt\n#   2. MSBuild from a compatible VS installation\n#   3. MSBuild from the xcopy tool package\n#\n# Returns full path to msbuild.exe.\n# Throws on failure.\n#\nfunction InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = $null) {\n  if (-not (IsWindowsPlatform)) {\n    throw \"Cannot initialize Visual Studio on non-Windows\"\n  }\n\n  if (Test-Path variable:global:_MSBuildExe) {\n    return $global:_MSBuildExe\n  }\n\n  # Minimum VS version to require.\n  $vsMinVersionReqdStr = '17.7'\n  $vsMinVersionReqd = [Version]::new($vsMinVersionReqdStr)\n\n  # If the version of msbuild is going to be xcopied,\n  # use this version. Version matches a package here:\n  # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.12.0\n  $defaultXCopyMSBuildVersion = '17.12.0'\n\n  if (!$vsRequirements) {\n    if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') {\n      $vsRequirements = $GlobalJson.tools.vs\n    }\n    else {\n      $vsRequirements = New-Object PSObject -Property @{ version = $vsMinVersionReqdStr }\n    }\n  }\n  $vsMinVersionStr = if ($vsRequirements.version) { $vsRequirements.version } else { $vsMinVersionReqdStr }\n  $vsMinVersion = [Version]::new($vsMinVersionStr)\n\n  # Try msbuild command available in the environment.\n  if ($env:VSINSTALLDIR -ne $null) {\n    $msbuildCmd = Get-Command 'msbuild.exe' -ErrorAction SilentlyContinue\n    if ($msbuildCmd -ne $null) {\n      # Workaround for https://github.com/dotnet/roslyn/issues/35793\n      # Due to this issue $msbuildCmd.Version returns 0.0.0.0 for msbuild.exe 16.2+\n      $msbuildVersion = [Version]::new((Get-Item $msbuildCmd.Path).VersionInfo.ProductVersion.Split([char[]]@('-', '+'))[0])\n\n      if ($msbuildVersion -ge $vsMinVersion) {\n        return $global:_MSBuildExe = $msbuildCmd.Path\n      }\n\n      # Report error - the developer environment is initialized with incompatible VS version.\n      throw \"Developer Command Prompt for VS $($env:VisualStudioVersion) is not recent enough. Please upgrade to $vsMinVersionStr or build from a plain CMD window\"\n    }\n  }\n\n  # Locate Visual Studio installation or download x-copy msbuild.\n  $vsInfo = LocateVisualStudio $vsRequirements\n  if ($vsInfo -ne $null) {\n    # Ensure vsInstallDir has a trailing slash\n    $vsInstallDir = Join-Path $vsInfo.installationPath \"\\\"\n    $vsMajorVersion = $vsInfo.installationVersion.Split('.')[0]\n\n    InitializeVisualStudioEnvironmentVariables $vsInstallDir $vsMajorVersion\n  } else {\n    if (Get-Member -InputObject $GlobalJson.tools -Name 'xcopy-msbuild') {\n      $xcopyMSBuildVersion = $GlobalJson.tools.'xcopy-msbuild'\n      $vsMajorVersion = $xcopyMSBuildVersion.Split('.')[0]\n    } else {\n      #if vs version provided in global.json is incompatible (too low) then use the default version for xcopy msbuild download\n      if($vsMinVersion -lt $vsMinVersionReqd){\n        Write-Host \"Using xcopy-msbuild version of $defaultXCopyMSBuildVersion since VS version $vsMinVersionStr provided in global.json is not compatible\"\n        $xcopyMSBuildVersion = $defaultXCopyMSBuildVersion\n        $vsMajorVersion = $xcopyMSBuildVersion.Split('.')[0]\n      }\n      else{\n        # If the VS version IS compatible, look for an xcopy msbuild package\n        # with a version matching VS.\n        # Note: If this version does not exist, then an explicit version of xcopy msbuild\n        # can be specified in global.json. This will be required for pre-release versions of msbuild.\n        $vsMajorVersion = $vsMinVersion.Major\n        $vsMinorVersion = $vsMinVersion.Minor\n        $xcopyMSBuildVersion = \"$vsMajorVersion.$vsMinorVersion.0\"\n      }\n    }\n\n    $vsInstallDir = $null\n    if ($xcopyMSBuildVersion.Trim() -ine \"none\") {\n        $vsInstallDir = InitializeXCopyMSBuild $xcopyMSBuildVersion $install\n        if ($vsInstallDir -eq $null) {\n            throw \"Could not xcopy msbuild. Please check that package 'Microsoft.DotNet.Arcade.MSBuild.Xcopy @ $xcopyMSBuildVersion' exists on feed 'dotnet-eng'.\"\n        }\n    }\n    if ($vsInstallDir -eq $null) {\n      throw 'Unable to find Visual Studio that has required version and components installed'\n    }\n  }\n\n  $msbuildVersionDir = if ([int]$vsMajorVersion -lt 16) { \"$vsMajorVersion.0\" } else { \"Current\" }\n\n  $local:BinFolder = Join-Path $vsInstallDir \"MSBuild\\$msbuildVersionDir\\Bin\"\n  $local:Prefer64bit = if (Get-Member -InputObject $vsRequirements -Name 'Prefer64bit') { $vsRequirements.Prefer64bit } else { $false }\n  if ($local:Prefer64bit -and (Test-Path(Join-Path $local:BinFolder \"amd64\"))) {\n    $global:_MSBuildExe = Join-Path $local:BinFolder \"amd64\\msbuild.exe\"\n  } else {\n    $global:_MSBuildExe = Join-Path $local:BinFolder \"msbuild.exe\"\n  }\n\n  return $global:_MSBuildExe\n}\n\nfunction InitializeVisualStudioEnvironmentVariables([string] $vsInstallDir, [string] $vsMajorVersion) {\n  $env:VSINSTALLDIR = $vsInstallDir\n  Set-Item \"env:VS$($vsMajorVersion)0COMNTOOLS\" (Join-Path $vsInstallDir \"Common7\\Tools\\\")\n\n  $vsSdkInstallDir = Join-Path $vsInstallDir \"VSSDK\\\"\n  if (Test-Path $vsSdkInstallDir) {\n    Set-Item \"env:VSSDK$($vsMajorVersion)0Install\" $vsSdkInstallDir\n    $env:VSSDKInstall = $vsSdkInstallDir\n  }\n}\n\nfunction InstallXCopyMSBuild([string]$packageVersion) {\n  return InitializeXCopyMSBuild $packageVersion -install $true\n}\n\nfunction InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) {\n  $packageName = 'Microsoft.DotNet.Arcade.MSBuild.Xcopy'\n  $packageDir = Join-Path $ToolsDir \"msbuild\\$packageVersion\"\n  $packagePath = Join-Path $packageDir \"$packageName.$packageVersion.nupkg\"\n\n  if (!(Test-Path $packageDir)) {\n    if (!$install) {\n      return $null\n    }\n\n    Create-Directory $packageDir\n\n    Write-Host \"Downloading $packageName $packageVersion\"\n    $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit\n    Retry({\n      Invoke-WebRequest \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg\" -OutFile $packagePath\n    })\n\n    if (!(Test-Path $packagePath)) {\n      Write-PipelineTelemetryError -Category 'InitializeToolset' -Message \"See https://dev.azure.com/dnceng/internal/_wiki/wikis/DNCEng%20Services%20Wiki/1074/Updating-Microsoft.DotNet.Arcade.MSBuild.Xcopy-WAS-RoslynTools.MSBuild-(xcopy-msbuild)-generation?anchor=troubleshooting for help troubleshooting issues with XCopy MSBuild\"\n      throw\n    }\n    Unzip $packagePath $packageDir\n  }\n\n  return Join-Path $packageDir 'tools'\n}\n\n#\n# Locates Visual Studio instance that meets the minimal requirements specified by tools.vs object in global.json.\n#\n# The following properties of tools.vs are recognized:\n#   \"version\": \"{major}.{minor}\"\n#       Two part minimal VS version, e.g. \"15.9\", \"16.0\", etc.\n#   \"components\": [\"componentId1\", \"componentId2\", ...]\n#       Array of ids of workload components that must be available in the VS instance.\n#       See e.g. https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-enterprise?view=vs-2017\n#\n# Returns JSON describing the located VS instance (same format as returned by vswhere),\n# or $null if no instance meeting the requirements is found on the machine.\n#\nfunction LocateVisualStudio([object]$vsRequirements = $null){\n  if (-not (IsWindowsPlatform)) {\n    throw \"Cannot run vswhere on non-Windows platforms.\"\n  }\n\n  if (Get-Member -InputObject $GlobalJson.tools -Name 'vswhere') {\n    $vswhereVersion = $GlobalJson.tools.vswhere\n  } else {\n    $vswhereVersion = '2.5.2'\n  }\n\n  $vsWhereDir = Join-Path $ToolsDir \"vswhere\\$vswhereVersion\"\n  $vsWhereExe = Join-Path $vsWhereDir 'vswhere.exe'\n\n  if (!(Test-Path $vsWhereExe)) {\n    Create-Directory $vsWhereDir\n    Write-Host 'Downloading vswhere'\n    Retry({\n      Invoke-WebRequest \"https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe\" -OutFile $vswhereExe\n    })\n  }\n\n  if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs }\n  $args = @('-latest', '-format', 'json', '-requires', 'Microsoft.Component.MSBuild', '-products', '*')\n\n  if (!$excludePrereleaseVS) {\n    $args += '-prerelease'\n  }\n\n  if (Get-Member -InputObject $vsRequirements -Name 'version') {\n    $args += '-version'\n    $args += $vsRequirements.version\n  }\n\n  if (Get-Member -InputObject $vsRequirements -Name 'components') {\n    foreach ($component in $vsRequirements.components) {\n      $args += '-requires'\n      $args += $component\n    }\n  }\n\n  $vsInfo =& $vsWhereExe $args | ConvertFrom-Json\n\n  if ($lastExitCode -ne 0) {\n    return $null\n  }\n\n  # use first matching instance\n  return $vsInfo[0]\n}\n\nfunction InitializeBuildTool() {\n  if (Test-Path variable:global:_BuildTool) {\n    # If the requested msbuild parameters do not match, clear the cached variables.\n    if($global:_BuildTool.Contains('ExcludePrereleaseVS') -and $global:_BuildTool.ExcludePrereleaseVS -ne $excludePrereleaseVS) {\n      Remove-Item variable:global:_BuildTool\n      Remove-Item variable:global:_MSBuildExe\n    } else {\n      return $global:_BuildTool\n    }\n  }\n\n  if (-not $msbuildEngine) {\n    $msbuildEngine = GetDefaultMSBuildEngine\n  }\n\n  # Initialize dotnet cli if listed in 'tools'\n  $dotnetRoot = $null\n  if (Get-Member -InputObject $GlobalJson.tools -Name 'dotnet') {\n    $dotnetRoot = InitializeDotNetCli -install:$restore\n  }\n\n  if ($msbuildEngine -eq 'dotnet') {\n    if (!$dotnetRoot) {\n      Write-PipelineTelemetryError -Category 'InitializeToolset' -Message \"/global.json must specify 'tools.dotnet'.\"\n      ExitWithExitCode 1\n    }\n    $dotnetPath = Join-Path $dotnetRoot (GetExecutableFileName 'dotnet')\n\n    $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = 'net' }\n  } elseif ($msbuildEngine -eq \"vs\") {\n    try {\n      $msbuildPath = InitializeVisualStudioMSBuild -install:$restore\n    } catch {\n      Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_\n      ExitWithExitCode 1\n    }\n\n    $buildTool = @{ Path = $msbuildPath; Command = \"\"; Tool = \"vs\"; Framework = \"netframework\"; ExcludePrereleaseVS = $excludePrereleaseVS }\n  } else {\n    Write-PipelineTelemetryError -Category 'InitializeToolset' -Message \"Unexpected value of -msbuildEngine: '$msbuildEngine'.\"\n    ExitWithExitCode 1\n  }\n\n  return $global:_BuildTool = $buildTool\n}\n\nfunction GetDefaultMSBuildEngine() {\n  # Presence of tools.vs indicates the repo needs to build using VS msbuild on Windows.\n  if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') {\n    return 'vs'\n  }\n\n  if (Get-Member -InputObject $GlobalJson.tools -Name 'dotnet') {\n    return 'dotnet'\n  }\n\n  Write-PipelineTelemetryError -Category 'InitializeToolset' -Message \"-msbuildEngine must be specified, or /global.json must specify 'tools.dotnet' or 'tools.vs'.\"\n  ExitWithExitCode 1\n}\n\nfunction GetNuGetPackageCachePath() {\n  if ($env:NUGET_PACKAGES -eq $null) {\n    # Use local cache on CI to ensure deterministic build.\n    # Avoid using the http cache as workaround for https://github.com/NuGet/Home/issues/3116\n    # use global cache in dev builds to avoid cost of downloading packages.\n    # For directory normalization, see also: https://github.com/NuGet/Home/issues/7968\n    if ($useGlobalNuGetCache) {\n      $env:NUGET_PACKAGES = Join-Path $env:UserProfile '.nuget\\packages\\'\n    } else {\n      $env:NUGET_PACKAGES = Join-Path $RepoRoot '.packages\\'\n      $env:RESTORENOHTTPCACHE = $true\n    }\n  }\n\n  return $env:NUGET_PACKAGES\n}\n\n# Returns a full path to an Arcade SDK task project file.\nfunction GetSdkTaskProject([string]$taskName) {\n  return Join-Path (Split-Path (InitializeToolset) -Parent) \"SdkTasks\\$taskName.proj\"\n}\n\nfunction InitializeNativeTools() {\n  if (-Not (Test-Path variable:DisableNativeToolsetInstalls) -And (Get-Member -InputObject $GlobalJson -Name \"native-tools\")) {\n    $nativeArgs= @{}\n    if ($ci) {\n      $nativeArgs = @{\n        InstallDirectory = \"$ToolsDir\"\n      }\n    }\n    if ($env:NativeToolsOnMachine) {\n      Write-Host \"Variable NativeToolsOnMachine detected, enabling native tool path promotion...\"\n      $nativeArgs += @{ PathPromotion = $true }\n    }\n    & \"$PSScriptRoot/init-tools-native.ps1\" @nativeArgs\n  }\n}\n\nfunction Read-ArcadeSdkVersion() {\n  return $GlobalJson.'msbuild-sdks'.'Microsoft.DotNet.Arcade.Sdk'\n}\n\nfunction InitializeToolset() {\n  # For Unified Build/Source-build support, check whether the environment variable is\n  # set. If it is, then use this as the toolset build project.\n  if ($env:_InitializeToolset -ne $null) {\n    return $global:_InitializeToolset = $env:_InitializeToolset\n  }\n\n  if (Test-Path variable:global:_InitializeToolset) {\n    return $global:_InitializeToolset\n  }\n\n  $nugetCache = GetNuGetPackageCachePath\n\n  $toolsetVersion = Read-ArcadeSdkVersion\n  $toolsetLocationFile = Join-Path $ToolsetDir \"$toolsetVersion.txt\"\n\n  if (Test-Path $toolsetLocationFile) {\n    $path = Get-Content $toolsetLocationFile -TotalCount 1\n    if (Test-Path $path) {\n      return $global:_InitializeToolset = $path\n    }\n  }\n\n  if (-not $restore) {\n    Write-PipelineTelemetryError -Category 'InitializeToolset' -Message \"Toolset version $toolsetVersion has not been restored.\"\n    ExitWithExitCode 1\n  }\n\n  $buildTool = InitializeBuildTool\n\n  $proj = Join-Path $ToolsetDir 'restore.proj'\n  $bl = if ($binaryLog) { '/bl:' + (Join-Path $LogDir 'ToolsetRestore.binlog') } else { '' }\n\n  '<Project Sdk=\"Microsoft.DotNet.Arcade.Sdk\"/>' | Set-Content $proj\n\n  MSBuild-Core $proj $bl /t:__WriteToolsetLocation /clp:ErrorsOnly`;NoSummary /p:__ToolsetLocationOutputFile=$toolsetLocationFile\n\n  $path = Get-Content $toolsetLocationFile -Encoding UTF8 -TotalCount 1\n  if (!(Test-Path $path)) {\n    throw \"Invalid toolset path: $path\"\n  }\n\n  return $global:_InitializeToolset = $path\n}\n\nfunction ExitWithExitCode([int] $exitCode) {\n  if ($ci -and $prepareMachine) {\n    Stop-Processes\n  }\n  exit $exitCode\n}\n\n# Check if $LASTEXITCODE is a nonzero exit code (NZEC). If so, print a Azure Pipeline error for\n# diagnostics, then exit the script with the $LASTEXITCODE.\nfunction Exit-IfNZEC([string] $category = \"General\") {\n  Write-Host \"Exit code $LASTEXITCODE\"\n  if ($LASTEXITCODE -ne 0) {\n    $message = \"Last command failed with exit code $LASTEXITCODE.\"\n    Write-PipelineTelemetryError -Force -Category $category -Message $message\n    ExitWithExitCode $LASTEXITCODE\n  }\n}\n\nfunction Stop-Processes() {\n  Write-Host 'Killing running build processes...'\n  foreach ($processName in $processesToStopOnExit) {\n    Get-Process -Name $processName -ErrorAction SilentlyContinue | Stop-Process\n  }\n}\n\n#\n# Executes msbuild (or 'dotnet msbuild') with arguments passed to the function.\n# The arguments are automatically quoted.\n# Terminates the script if the build fails.\n#\nfunction MSBuild() {\n  if ($pipelinesLog) {\n    $buildTool = InitializeBuildTool\n\n    if ($ci -and $buildTool.Tool -eq 'dotnet') {\n      $env:NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS = 20\n      $env:NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS = 20\n      Write-PipelineSetVariable -Name 'NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS' -Value '20'\n      Write-PipelineSetVariable -Name 'NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS' -Value '20'\n    }\n\n    Enable-Nuget-EnhancedRetry\n\n    $toolsetBuildProject = InitializeToolset\n    $basePath = Split-Path -parent $toolsetBuildProject\n    $possiblePaths = @(\n      # new scripts need to work with old packages, so we need to look for the old names/versions\n      (Join-Path $basePath (Join-Path $buildTool.Framework 'Microsoft.DotNet.ArcadeLogging.dll')),\n      (Join-Path $basePath (Join-Path $buildTool.Framework 'Microsoft.DotNet.Arcade.Sdk.dll')),\n\n      # This list doesn't need to be updated anymore and can eventually be removed.\n      (Join-Path $basePath (Join-Path net9.0 'Microsoft.DotNet.ArcadeLogging.dll')),\n      (Join-Path $basePath (Join-Path net9.0 'Microsoft.DotNet.Arcade.Sdk.dll')),\n      (Join-Path $basePath (Join-Path net8.0 'Microsoft.DotNet.ArcadeLogging.dll')),\n      (Join-Path $basePath (Join-Path net8.0 'Microsoft.DotNet.Arcade.Sdk.dll'))\n    )\n    $selectedPath = $null\n    foreach ($path in $possiblePaths) {\n      if (Test-Path $path -PathType Leaf) {\n        $selectedPath = $path\n        break\n      }\n    }\n    if (-not $selectedPath) {\n      Write-PipelineTelemetryError -Category 'Build' -Message 'Unable to find arcade sdk logger assembly.'\n      ExitWithExitCode 1\n    }\n    $args += \"/logger:$selectedPath\"\n  }\n\n  MSBuild-Core @args\n}\n\n#\n# Executes msbuild (or 'dotnet msbuild') with arguments passed to the function.\n# The arguments are automatically quoted.\n# Terminates the script if the build fails.\n#\nfunction MSBuild-Core() {\n  if ($ci) {\n    if (!$binaryLog -and !$excludeCIBinarylog) {\n      Write-PipelineTelemetryError -Category 'Build' -Message 'Binary log must be enabled in CI build, or explicitly opted-out from with the -excludeCIBinarylog switch.'\n      ExitWithExitCode 1\n    }\n\n    if ($nodeReuse) {\n      Write-PipelineTelemetryError -Category 'Build' -Message 'Node reuse must be disabled in CI build.'\n      ExitWithExitCode 1\n    }\n  }\n\n  Enable-Nuget-EnhancedRetry\n\n  $buildTool = InitializeBuildTool\n\n  $cmdArgs = \"$($buildTool.Command) /m /nologo /clp:Summary /v:$verbosity /nr:$nodeReuse /p:ContinuousIntegrationBuild=$ci\"\n\n  if ($warnAsError) {\n    $cmdArgs += ' /warnaserror /p:TreatWarningsAsErrors=true'\n  }\n  else {\n    $cmdArgs += ' /p:TreatWarningsAsErrors=false'\n  }\n\n  foreach ($arg in $args) {\n    if ($null -ne $arg -and $arg.Trim() -ne \"\") {\n      if ($arg.EndsWith('\\')) {\n        $arg = $arg + \"\\\"\n      }\n      $cmdArgs += \" `\"$arg`\"\"\n    }\n  }\n\n  # Be sure quote the path in case there are spaces in the dotnet installation location.\n  $env:ARCADE_BUILD_TOOL_COMMAND = \"`\"$($buildTool.Path)`\" $cmdArgs\"\n\n  $exitCode = Exec-Process $buildTool.Path $cmdArgs\n\n  if ($exitCode -ne 0) {\n    # We should not Write-PipelineTaskError here because that message shows up in the build summary\n    # The build already logged an error, that's the reason it failed. Producing an error here only adds noise.\n    Write-Host \"Build failed with exit code $exitCode. Check errors above.\" -ForegroundColor Red\n\n    $buildLog = GetMSBuildBinaryLogCommandLineArgument $args\n    if ($null -ne $buildLog) {\n      Write-Host \"See log: $buildLog\" -ForegroundColor DarkGray\n    }\n\n    # When running on Azure Pipelines, override the returned exit code to avoid double logging.\n    # Skip this when the build is a child of the VMR orchestrator build.\n    if ($ci -and $env:SYSTEM_TEAMPROJECT -ne $null -and !$productBuild -and -not($properties -like \"*DotNetBuildRepo=true*\")) {\n      Write-PipelineSetResult -Result \"Failed\" -Message \"msbuild execution failed.\"\n      # Exiting with an exit code causes the azure pipelines task to log yet another \"noise\" error\n      # The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error\n      ExitWithExitCode 0\n    } else {\n      ExitWithExitCode $exitCode\n    }\n  }\n}\n\nfunction GetMSBuildBinaryLogCommandLineArgument($arguments) {\n  foreach ($argument in $arguments) {\n    if ($argument -ne $null) {\n      $arg = $argument.Trim()\n      if ($arg.StartsWith('/bl:', \"OrdinalIgnoreCase\")) {\n        return $arg.Substring('/bl:'.Length)\n      }\n\n      if ($arg.StartsWith('/binaryLogger:', 'OrdinalIgnoreCase')) {\n        return $arg.Substring('/binaryLogger:'.Length)\n      }\n    }\n  }\n\n  return $null\n}\n\nfunction GetExecutableFileName($baseName) {\n  if (IsWindowsPlatform) {\n    return \"$baseName.exe\"\n  }\n  else {\n    return $baseName\n  }\n}\n\nfunction IsWindowsPlatform() {\n  return [environment]::OSVersion.Platform -eq [PlatformID]::Win32NT\n}\n\nfunction Get-Darc($version) {\n  $darcPath  = \"$TempDir\\darc\\$([guid]::NewGuid())\"\n  if ($version -ne $null) {\n    & $PSScriptRoot\\darc-init.ps1 -toolpath $darcPath -darcVersion $version | Out-Host\n  } else {\n    & $PSScriptRoot\\darc-init.ps1 -toolpath $darcPath | Out-Host\n  }\n  return \"$darcPath\\darc.exe\"\n}\n\n. $PSScriptRoot\\pipeline-logging-functions.ps1\n\n$RepoRoot = Resolve-Path (Join-Path $PSScriptRoot '..\\..\\')\n$EngRoot = Resolve-Path (Join-Path $PSScriptRoot '..')\n$ArtifactsDir = Join-Path $RepoRoot 'artifacts'\n$ToolsetDir = Join-Path $ArtifactsDir 'toolset'\n$ToolsDir = Join-Path $RepoRoot '.tools'\n$LogDir = Join-Path (Join-Path $ArtifactsDir 'log') $configuration\n$TempDir = Join-Path (Join-Path $ArtifactsDir 'tmp') $configuration\n$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot 'global.json') | ConvertFrom-Json\n# true if global.json contains a \"runtimes\" section\n$globalJsonHasRuntimes = if ($GlobalJson.tools.PSObject.Properties.Name -Match 'runtimes') { $true } else { $false }\n\nCreate-Directory $ToolsetDir\nCreate-Directory $TempDir\nCreate-Directory $LogDir\n\nWrite-PipelineSetVariable -Name 'Artifacts' -Value $ArtifactsDir\nWrite-PipelineSetVariable -Name 'Artifacts.Toolset' -Value $ToolsetDir\nWrite-PipelineSetVariable -Name 'Artifacts.Log' -Value $LogDir\nWrite-PipelineSetVariable -Name 'TEMP' -Value $TempDir\nWrite-PipelineSetVariable -Name 'TMP' -Value $TempDir\n\n# Import custom tools configuration, if present in the repo.\n# Note: Import in global scope so that the script set top-level variables without qualification.\nif (!$disableConfigureToolsetImport) {\n  $configureToolsetScript = Join-Path $EngRoot 'configure-toolset.ps1'\n  if (Test-Path $configureToolsetScript) {\n    . $configureToolsetScript\n    if ((Test-Path variable:failOnConfigureToolsetError) -And $failOnConfigureToolsetError) {\n      if ((Test-Path variable:LastExitCode) -And ($LastExitCode -ne 0)) {\n        Write-PipelineTelemetryError -Category 'Build' -Message 'configure-toolset.ps1 returned a non-zero exit code'\n        ExitWithExitCode $LastExitCode\n      }\n    }\n  }\n}\n\n#\n# If $ci flag is set, turn on (and log that we did) special environment variables for improved Nuget client retry logic.\n#\nfunction Enable-Nuget-EnhancedRetry() {\n    if ($ci) {\n      Write-Host \"Setting NUGET enhanced retry environment variables\"\n      $env:NUGET_ENABLE_ENHANCED_HTTP_RETRY = 'true'\n      $env:NUGET_ENHANCED_MAX_NETWORK_TRY_COUNT = 6\n      $env:NUGET_ENHANCED_NETWORK_RETRY_DELAY_MILLISECONDS = 1000\n      $env:NUGET_RETRY_HTTP_429 = 'true'\n      Write-PipelineSetVariable -Name 'NUGET_ENABLE_ENHANCED_HTTP_RETRY' -Value 'true'\n      Write-PipelineSetVariable -Name 'NUGET_ENHANCED_MAX_NETWORK_TRY_COUNT' -Value '6'\n      Write-PipelineSetVariable -Name 'NUGET_ENHANCED_NETWORK_RETRY_DELAY_MILLISECONDS' -Value '1000'\n      Write-PipelineSetVariable -Name 'NUGET_RETRY_HTTP_429' -Value 'true'\n    }\n}\n"
  },
  {
    "path": "eng/common/tools.sh",
    "content": "#!/usr/bin/env bash\n\n# Initialize variables if they aren't already defined.\n\n# CI mode - set to true on CI server for PR validation build or official build.\nci=${ci:-false}\n\n# Set to true to use the pipelines logger which will enable Azure logging output.\n# https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md\n# This flag is meant as a temporary opt-opt for the feature while validate it across\n# our consumers. It will be deleted in the future.\nif [[ \"$ci\" == true ]]; then\n  pipelines_log=${pipelines_log:-true}\nelse\n  pipelines_log=${pipelines_log:-false}\nfi\n\n# Build configuration. Common values include 'Debug' and 'Release', but the repository may use other names.\nconfiguration=${configuration:-'Debug'}\n\n# Set to true to opt out of outputting binary log while running in CI\nexclude_ci_binary_log=${exclude_ci_binary_log:-false}\n\nif [[ \"$ci\" == true && \"$exclude_ci_binary_log\" == false ]]; then\n  binary_log_default=true\nelse\n  binary_log_default=false\nfi\n\n# Set to true to output binary log from msbuild. Note that emitting binary log slows down the build.\nbinary_log=${binary_log:-$binary_log_default}\n\n# Turns on machine preparation/clean up code that changes the machine state (e.g. kills build processes).\nprepare_machine=${prepare_machine:-false}\n\n# True to restore toolsets and dependencies.\nrestore=${restore:-true}\n\n# Adjusts msbuild verbosity level.\nverbosity=${verbosity:-'minimal'}\n\n# Set to true to reuse msbuild nodes. Recommended to not reuse on CI.\nif [[ \"$ci\" == true ]]; then\n  node_reuse=${node_reuse:-false}\nelse\n  node_reuse=${node_reuse:-true}\nfi\n\n# Configures warning treatment in msbuild.\nwarn_as_error=${warn_as_error:-true}\n\n# True to attempt using .NET Core already that meets requirements specified in global.json\n# installed on the machine instead of downloading one.\nuse_installed_dotnet_cli=${use_installed_dotnet_cli:-true}\n\n# Enable repos to use a particular version of the on-line dotnet-install scripts.\n#    default URL: https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh\ndotnetInstallScriptVersion=${dotnetInstallScriptVersion:-'v1'}\n\n# True to use global NuGet cache instead of restoring packages to repository-local directory.\nif [[ \"$ci\" == true ]]; then\n  use_global_nuget_cache=${use_global_nuget_cache:-false}\nelse\n  use_global_nuget_cache=${use_global_nuget_cache:-true}\nfi\n\n# Used when restoring .NET SDK from alternative feeds\nruntime_source_feed=${runtime_source_feed:-''}\nruntime_source_feed_key=${runtime_source_feed_key:-''}\n\n# True if the build is a product build\nproduct_build=${product_build:-false}\n\n# Resolve any symlinks in the given path.\nfunction ResolvePath {\n  local path=$1\n\n  while [[ -h $path ]]; do\n    local dir=\"$( cd -P \"$( dirname \"$path\" )\" && pwd )\"\n    path=\"$(readlink \"$path\")\"\n\n    # if $path was a relative symlink, we need to resolve it relative to the path where the\n    # symlink file was located\n    [[ $path != /* ]] && path=\"$dir/$path\"\n  done\n\n  # return value\n  _ResolvePath=\"$path\"\n}\n\n# ReadVersionFromJson [json key]\nfunction ReadGlobalVersion {\n  local key=$1\n\n  if command -v jq &> /dev/null; then\n    _ReadGlobalVersion=\"$(jq -r \".[] | select(has(\\\"$key\\\")) | .\\\"$key\\\"\" \"$global_json_file\")\"\n  elif [[ \"$(cat \"$global_json_file\")\" =~ \\\"$key\\\"[[:space:]\\:]*\\\"([^\\\"]+) ]]; then\n    _ReadGlobalVersion=${BASH_REMATCH[1]}\n  fi\n\n  if [[ -z \"$_ReadGlobalVersion\" ]]; then\n    Write-PipelineTelemetryError -category 'Build' \"Error: Cannot find \\\"$key\\\" in $global_json_file\"\n    ExitWithExitCode 1\n  fi\n}\n\nfunction InitializeDotNetCli {\n  if [[ -n \"${_InitializeDotNetCli:-}\" ]]; then\n    return\n  fi\n\n  local install=$1\n\n  # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism\n  export DOTNET_MULTILEVEL_LOOKUP=0\n\n  # Disable first run since we want to control all package sources\n  export DOTNET_NOLOGO=1\n\n  # Disable telemetry on CI\n  if [[ $ci == true ]]; then\n    export DOTNET_CLI_TELEMETRY_OPTOUT=1\n  fi\n\n  # LTTNG is the logging infrastructure used by Core CLR. Need this variable set\n  # so it doesn't output warnings to the console.\n  export LTTNG_HOME=\"$HOME\"\n\n  # Find the first path on $PATH that contains the dotnet.exe\n  if [[ \"$use_installed_dotnet_cli\" == true && $global_json_has_runtimes == false && -z \"${DOTNET_INSTALL_DIR:-}\" ]]; then\n    local dotnet_path=`command -v dotnet`\n    if [[ -n \"$dotnet_path\" ]]; then\n      ResolvePath \"$dotnet_path\"\n      export DOTNET_INSTALL_DIR=`dirname \"$_ResolvePath\"`\n    fi\n  fi\n\n  ReadGlobalVersion \"dotnet\"\n  local dotnet_sdk_version=$_ReadGlobalVersion\n  local dotnet_root=\"\"\n\n  # Use dotnet installation specified in DOTNET_INSTALL_DIR if it contains the required SDK version,\n  # otherwise install the dotnet CLI and SDK to repo local .dotnet directory to avoid potential permission issues.\n  if [[ $global_json_has_runtimes == false && -n \"${DOTNET_INSTALL_DIR:-}\" && -d \"$DOTNET_INSTALL_DIR/sdk/$dotnet_sdk_version\" ]]; then\n    dotnet_root=\"$DOTNET_INSTALL_DIR\"\n  else\n    dotnet_root=\"${repo_root}.dotnet\"\n\n    export DOTNET_INSTALL_DIR=\"$dotnet_root\"\n\n    if [[ ! -d \"$DOTNET_INSTALL_DIR/sdk/$dotnet_sdk_version\" ]]; then\n      if [[ \"$install\" == true ]]; then\n        InstallDotNetSdk \"$dotnet_root\" \"$dotnet_sdk_version\"\n      else\n        Write-PipelineTelemetryError -category 'InitializeToolset' \"Unable to find dotnet with SDK version '$dotnet_sdk_version'\"\n        ExitWithExitCode 1\n      fi\n    fi\n  fi\n\n  # Add dotnet to PATH. This prevents any bare invocation of dotnet in custom\n  # build steps from using anything other than what we've downloaded.\n  Write-PipelinePrependPath -path \"$dotnet_root\"\n\n  Write-PipelineSetVariable -name \"DOTNET_MULTILEVEL_LOOKUP\" -value \"0\"\n  Write-PipelineSetVariable -name \"DOTNET_NOLOGO\" -value \"1\"\n\n  # return value\n  _InitializeDotNetCli=\"$dotnet_root\"\n}\n\nfunction InstallDotNetSdk {\n  local root=$1\n  local version=$2\n  local architecture=\"unset\"\n  if [[ $# -ge 3 ]]; then\n    architecture=$3\n  fi\n  InstallDotNet \"$root\" \"$version\" $architecture 'sdk' 'true' $runtime_source_feed $runtime_source_feed_key\n}\n\nfunction InstallDotNet {\n  local root=$1\n  local version=$2\n  local runtime=$4\n\n  local dotnetVersionLabel=\"'$runtime v$version'\"\n  if [[ -n \"${4:-}\" ]] && [ \"$4\" != 'sdk' ]; then\n    runtimePath=\"$root\"\n    runtimePath=\"$runtimePath/shared\"\n    case \"$runtime\" in\n      dotnet)\n        runtimePath=\"$runtimePath/Microsoft.NETCore.App\"\n        ;;\n      aspnetcore)\n        runtimePath=\"$runtimePath/Microsoft.AspNetCore.App\"\n        ;;\n      windowsdesktop)\n        runtimePath=\"$runtimePath/Microsoft.WindowsDesktop.App\"\n        ;;\n      *)\n        ;;\n    esac\n    runtimePath=\"$runtimePath/$version\"\n\n    dotnetVersionLabel=\"runtime toolset '$runtime/$architecture v$version'\"\n\n    if [ -d \"$runtimePath\" ]; then\n      echo \"  Runtime toolset '$runtime/$architecture v$version' already installed.\"\n      local installSuccess=1\n      return\n    fi\n  fi\n\n  GetDotNetInstallScript \"$root\"\n  local install_script=$_GetDotNetInstallScript\n\n  local installParameters=(--version $version --install-dir \"$root\")\n\n  if [[ -n \"${3:-}\" ]] && [ \"$3\" != 'unset' ]; then\n    installParameters+=(--architecture $3)\n  fi\n  if [[ -n \"${4:-}\" ]] && [ \"$4\" != 'sdk' ]; then\n    installParameters+=(--runtime $4)\n  fi\n  if [[ \"$#\" -ge \"5\" ]] && [[ \"$5\" != 'false' ]]; then\n    installParameters+=(--skip-non-versioned-files)\n  fi\n\n  local variations=() # list of variable names with parameter arrays in them\n\n  local public_location=(\"${installParameters[@]}\")\n  variations+=(public_location)\n\n  local dotnetbuilds=(\"${installParameters[@]}\" --azure-feed \"https://ci.dot.net/public\")\n  variations+=(dotnetbuilds)\n\n  if [[ -n \"${6:-}\" ]]; then\n    variations+=(private_feed)\n    local private_feed=(\"${installParameters[@]}\" --azure-feed $6)\n    if [[ -n \"${7:-}\" ]]; then\n      # The 'base64' binary on alpine uses '-d' and doesn't support '--decode'\n      # '-d'. To work around this, do a simple detection and switch the parameter\n      # accordingly.\n      decodeArg=\"--decode\"\n      if base64 --help 2>&1 | grep -q \"BusyBox\"; then\n          decodeArg=\"-d\"\n      fi\n      decodedFeedKey=`echo $7 | base64 $decodeArg`\n      private_feed+=(--feed-credential $decodedFeedKey)\n    fi\n  fi\n\n  local installSuccess=0\n  for variationName in \"${variations[@]}\"; do\n    local name=\"$variationName[@]\"\n    local variation=(\"${!name}\")\n    echo \"  Attempting to install $dotnetVersionLabel from $variationName.\"\n    bash \"$install_script\" \"${variation[@]}\" && installSuccess=1\n    if [[ \"$installSuccess\" -eq 1 ]]; then\n      break\n    fi\n\n    echo \"  Failed to install $dotnetVersionLabel from $variationName.\"\n  done\n\n  if [[ \"$installSuccess\" -eq 0 ]]; then\n    Write-PipelineTelemetryError -category 'InitializeToolset' \"Failed to install $dotnetVersionLabel from any of the specified locations.\"\n    ExitWithExitCode 1\n  fi\n}\n\nfunction with_retries {\n  local maxRetries=5\n  local retries=1\n  echo \"Trying to run '$@' for maximum of $maxRetries attempts.\"\n  while [[ $((retries++)) -le $maxRetries ]]; do\n    \"$@\"\n\n    if [[ $? == 0 ]]; then\n      echo \"Ran '$@' successfully.\"\n      return 0\n    fi\n\n    timeout=$((3**$retries-1))\n    echo \"Failed to execute '$@'. Waiting $timeout seconds before next attempt ($retries out of $maxRetries).\" 1>&2\n    sleep $timeout\n  done\n\n  echo \"Failed to execute '$@' for $maxRetries times.\" 1>&2\n\n  return 1\n}\n\nfunction GetDotNetInstallScript {\n  local root=$1\n  local install_script=\"$root/dotnet-install.sh\"\n  local install_script_url=\"https://dotnet.microsoft.com/download/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.sh\"\n\n  if [[ ! -a \"$install_script\" ]]; then\n    mkdir -p \"$root\"\n\n    echo \"Downloading '$install_script_url'\"\n\n    # Use curl if available, otherwise use wget\n    if command -v curl > /dev/null; then\n      # first, try directly, if this fails we will retry with verbose logging\n      curl \"$install_script_url\" -sSL --retry 10 --create-dirs -o \"$install_script\" || {\n        if command -v openssl &> /dev/null; then\n          echo \"Curl failed; dumping some information about dotnet.microsoft.com for later investigation\"\n          echo | openssl s_client -showcerts -servername dotnet.microsoft.com  -connect dotnet.microsoft.com:443 || true\n        fi\n        echo \"Will now retry the same URL with verbose logging.\"\n        with_retries curl \"$install_script_url\" -sSL --verbose --retry 10 --create-dirs -o \"$install_script\" || {\n          local exit_code=$?\n          Write-PipelineTelemetryError -category 'InitializeToolset' \"Failed to acquire dotnet install script (exit code '$exit_code').\"\n          ExitWithExitCode $exit_code\n        }\n      }\n    else\n      with_retries wget -v -O \"$install_script\" \"$install_script_url\" || {\n        local exit_code=$?\n        Write-PipelineTelemetryError -category 'InitializeToolset' \"Failed to acquire dotnet install script (exit code '$exit_code').\"\n        ExitWithExitCode $exit_code\n      }\n    fi\n  fi\n  # return value\n  _GetDotNetInstallScript=\"$install_script\"\n}\n\nfunction InitializeBuildTool {\n  if [[ -n \"${_InitializeBuildTool:-}\" ]]; then\n    return\n  fi\n\n  InitializeDotNetCli $restore\n\n  # return values\n  _InitializeBuildTool=\"$_InitializeDotNetCli/dotnet\"\n  _InitializeBuildToolCommand=\"msbuild\"\n}\n\n# Set RestoreNoHttpCache as a workaround for https://github.com/NuGet/Home/issues/3116\nfunction GetNuGetPackageCachePath {\n  if [[ -z ${NUGET_PACKAGES:-} ]]; then\n    if [[ \"$use_global_nuget_cache\" == true ]]; then\n      export NUGET_PACKAGES=\"$HOME/.nuget/packages/\"\n    else\n      export NUGET_PACKAGES=\"$repo_root/.packages/\"\n      export RESTORENOHTTPCACHE=true\n    fi\n  fi\n\n  # return value\n  _GetNuGetPackageCachePath=$NUGET_PACKAGES\n}\n\nfunction InitializeNativeTools() {\n  if [[ -n \"${DisableNativeToolsetInstalls:-}\" ]]; then\n    return\n  fi\n  if grep -Fq \"native-tools\" $global_json_file\n  then\n    local nativeArgs=\"\"\n    if [[ \"$ci\" == true ]]; then\n      nativeArgs=\"--installDirectory $tools_dir\"\n    fi\n    \"$_script_dir/init-tools-native.sh\" $nativeArgs\n  fi\n}\n\nfunction InitializeToolset {\n  if [[ -n \"${_InitializeToolset:-}\" ]]; then\n    return\n  fi\n\n  GetNuGetPackageCachePath\n\n  ReadGlobalVersion \"Microsoft.DotNet.Arcade.Sdk\"\n\n  local toolset_version=$_ReadGlobalVersion\n  local toolset_location_file=\"$toolset_dir/$toolset_version.txt\"\n\n  if [[ -a \"$toolset_location_file\" ]]; then\n    local path=`cat \"$toolset_location_file\"`\n    if [[ -a \"$path\" ]]; then\n      # return value\n      _InitializeToolset=\"$path\"\n      return\n    fi\n  fi\n\n  if [[ \"$restore\" != true ]]; then\n    Write-PipelineTelemetryError -category 'InitializeToolset' \"Toolset version $toolset_version has not been restored.\"\n    ExitWithExitCode 2\n  fi\n\n  local proj=\"$toolset_dir/restore.proj\"\n\n  local bl=\"\"\n  if [[ \"$binary_log\" == true ]]; then\n    bl=\"/bl:$log_dir/ToolsetRestore.binlog\"\n  fi\n\n  echo '<Project Sdk=\"Microsoft.DotNet.Arcade.Sdk\"/>' > \"$proj\"\n  MSBuild-Core \"$proj\" $bl /t:__WriteToolsetLocation /clp:ErrorsOnly\\;NoSummary /p:__ToolsetLocationOutputFile=\"$toolset_location_file\"\n\n  local toolset_build_proj=`cat \"$toolset_location_file\"`\n\n  if [[ ! -a \"$toolset_build_proj\" ]]; then\n    Write-PipelineTelemetryError -category 'Build' \"Invalid toolset path: $toolset_build_proj\"\n    ExitWithExitCode 3\n  fi\n\n  # return value\n  _InitializeToolset=\"$toolset_build_proj\"\n}\n\nfunction ExitWithExitCode {\n  if [[ \"$ci\" == true && \"$prepare_machine\" == true ]]; then\n    StopProcesses\n  fi\n  exit $1\n}\n\nfunction StopProcesses {\n  echo \"Killing running build processes...\"\n  pkill -9 \"dotnet\" || true\n  pkill -9 \"vbcscompiler\" || true\n  return 0\n}\n\nfunction MSBuild {\n  local args=( \"$@\" )\n  if [[ \"$pipelines_log\" == true ]]; then\n    InitializeBuildTool\n    InitializeToolset\n\n    if [[ \"$ci\" == true ]]; then\n      export NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=20\n      export NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=20\n      Write-PipelineSetVariable -name \"NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS\" -value \"20\"\n      Write-PipelineSetVariable -name \"NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS\" -value \"20\"\n    fi\n\n    local toolset_dir=\"${_InitializeToolset%/*}\"\n    # new scripts need to work with old packages, so we need to look for the old names/versions\n    local selectedPath=\n    local possiblePaths=()\n    possiblePaths+=( \"$toolset_dir/net/Microsoft.DotNet.ArcadeLogging.dll\" )\n    possiblePaths+=( \"$toolset_dir/net/Microsoft.DotNet.Arcade.Sdk.dll\" )\n\n    # This list doesn't need to be updated anymore and can eventually be removed.\n    possiblePaths+=( \"$toolset_dir/net9.0/Microsoft.DotNet.ArcadeLogging.dll\" )\n    possiblePaths+=( \"$toolset_dir/net9.0/Microsoft.DotNet.Arcade.Sdk.dll\" )\n    possiblePaths+=( \"$toolset_dir/net8.0/Microsoft.DotNet.ArcadeLogging.dll\" )\n    possiblePaths+=( \"$toolset_dir/net8.0/Microsoft.DotNet.Arcade.Sdk.dll\" )\n    for path in \"${possiblePaths[@]}\"; do\n      if [[ -f $path ]]; then\n        selectedPath=$path\n        break\n      fi\n    done\n    if [[ -z \"$selectedPath\" ]]; then\n      Write-PipelineTelemetryError -category 'Build'  \"Unable to find arcade sdk logger assembly.\"\n      ExitWithExitCode 1\n    fi\n    args+=( \"-logger:$selectedPath\" )\n  fi\n\n  MSBuild-Core \"${args[@]}\"\n}\n\nfunction MSBuild-Core {\n  if [[ \"$ci\" == true ]]; then\n    if [[ \"$binary_log\" != true && \"$exclude_ci_binary_log\" != true ]]; then\n      Write-PipelineTelemetryError -category 'Build'  \"Binary log must be enabled in CI build, or explicitly opted-out from with the -noBinaryLog switch.\"\n      ExitWithExitCode 1\n    fi\n\n    if [[ \"$node_reuse\" == true ]]; then\n      Write-PipelineTelemetryError -category 'Build'  \"Node reuse must be disabled in CI build.\"\n      ExitWithExitCode 1\n    fi\n  fi\n\n  InitializeBuildTool\n\n  local warnaserror_switch=\"\"\n  if [[ $warn_as_error == true ]]; then\n    warnaserror_switch=\"/warnaserror\"\n  fi\n\n  function RunBuildTool {\n    export ARCADE_BUILD_TOOL_COMMAND=\"$_InitializeBuildTool $@\"\n\n    \"$_InitializeBuildTool\" \"$@\" || {\n      local exit_code=$?\n      # We should not Write-PipelineTaskError here because that message shows up in the build summary\n      # The build already logged an error, that's the reason it failed. Producing an error here only adds noise.\n      echo \"Build failed with exit code $exit_code. Check errors above.\"\n\n      # When running on Azure Pipelines, override the returned exit code to avoid double logging.\n      # Skip this when the build is a child of the VMR orchestrator build.\n      if [[ \"$ci\" == true && -n ${SYSTEM_TEAMPROJECT:-} && \"$product_build\" != true && \"$properties\" != *\"DotNetBuildRepo=true\"* ]]; then\n        Write-PipelineSetResult -result \"Failed\" -message \"msbuild execution failed.\"\n        # Exiting with an exit code causes the azure pipelines task to log yet another \"noise\" error\n        # The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error\n        ExitWithExitCode 0\n      else\n        ExitWithExitCode $exit_code\n      fi\n    }\n  }\n\n  RunBuildTool \"$_InitializeBuildToolCommand\" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci \"$@\"\n}\n\nfunction GetDarc {\n    darc_path=\"$temp_dir/darc\"\n    version=\"$1\"\n\n    if [[ -n \"$version\" ]]; then\n      version=\"--darcversion $version\"\n    fi\n\n    \"$eng_root/common/darc-init.sh\" --toolpath \"$darc_path\" $version\n}\n\nResolvePath \"${BASH_SOURCE[0]}\"\n_script_dir=`dirname \"$_ResolvePath\"`\n\n. \"$_script_dir/pipeline-logging-functions.sh\"\n\neng_root=`cd -P \"$_script_dir/..\" && pwd`\nrepo_root=`cd -P \"$_script_dir/../..\" && pwd`\nrepo_root=\"${repo_root}/\"\nartifacts_dir=\"${repo_root}artifacts\"\ntoolset_dir=\"$artifacts_dir/toolset\"\ntools_dir=\"${repo_root}.tools\"\nlog_dir=\"$artifacts_dir/log/$configuration\"\ntemp_dir=\"$artifacts_dir/tmp/$configuration\"\n\nglobal_json_file=\"${repo_root}global.json\"\n# determine if global.json contains a \"runtimes\" entry\nglobal_json_has_runtimes=false\nif command -v jq &> /dev/null; then\n  if jq -e '.tools | has(\"runtimes\")' \"$global_json_file\" &> /dev/null; then\n    global_json_has_runtimes=true\n  fi\nelif [[ \"$(cat \"$global_json_file\")\" =~ \\\"runtimes\\\"[[:space:]\\:]*\\{ ]]; then\n  global_json_has_runtimes=true\nfi\n\n# HOME may not be defined in some scenarios, but it is required by NuGet\nif [[ -z $HOME ]]; then\n  export HOME=\"${repo_root}artifacts/.home/\"\n  mkdir -p \"$HOME\"\nfi\n\nmkdir -p \"$toolset_dir\"\nmkdir -p \"$temp_dir\"\nmkdir -p \"$log_dir\"\n\nWrite-PipelineSetVariable -name \"Artifacts\" -value \"$artifacts_dir\"\nWrite-PipelineSetVariable -name \"Artifacts.Toolset\" -value \"$toolset_dir\"\nWrite-PipelineSetVariable -name \"Artifacts.Log\" -value \"$log_dir\"\nWrite-PipelineSetVariable -name \"Temp\" -value \"$temp_dir\"\nWrite-PipelineSetVariable -name \"TMP\" -value \"$temp_dir\"\n\n# Import custom tools configuration, if present in the repo.\nif [ -z \"${disable_configure_toolset_import:-}\" ]; then\n  configure_toolset_script=\"$eng_root/configure-toolset.sh\"\n  if [[ -a \"$configure_toolset_script\" ]]; then\n    . \"$configure_toolset_script\"\n  fi\nfi\n\n# TODO: https://github.com/dotnet/arcade/issues/1468\n# Temporary workaround to avoid breaking change.\n# Remove once repos are updated.\nif [[ -n \"${useInstalledDotNetCli:-}\" ]]; then\n  use_installed_dotnet_cli=\"$useInstalledDotNetCli\"\nfi\n"
  },
  {
    "path": "global.json",
    "content": "{\n  \"tools\": {\n    \"dotnet\": \"10.0.100-alpha.1.24573.1\"\n  },\n  \"msbuild-sdks\": {\n    \"Microsoft.DotNet.Arcade.Sdk\": \"10.0.0-beta.25056.1\"\n  }\n}\n"
  },
  {
    "path": "src/Directory.Build.props",
    "content": "<Project>\n  <Import Project=\"$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))\" />\n\n  <PropertyGroup>\n    <EnableNETAnalyzers>true</EnableNETAnalyzers>\n    <CodeAnalysisRuleSet>$(RepoRoot)\\build\\analyzers\\rulesets\\Default.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\n  </PropertyGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/ApiConnection.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.txt file in the project root for more information.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.OpenApi;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl\n{\n    internal class ApiConnection\n    {\n        private readonly HttpState _httpState;\n        private readonly IWritable _logger;\n        private readonly bool _logVerboseMessages;\n        private readonly IOpenApiSearchPathsProvider _searchPaths;\n\n        public Uri? RootUri { get; set; }\n        public bool HasRootUri => RootUri is object;\n        public Uri? BaseUri { get; set; }\n        public bool HasBaseUri => BaseUri is object;\n        public Uri? SwaggerUri { get; set; }\n        public bool HasSwaggerUri => SwaggerUri is object;\n        public string? SwaggerDocument { get; set; }\n        public bool HasSwaggerDocument => SwaggerDocument is object;\n        public bool AllowBaseOverrideBySwagger { get; set; }\n\n        public ApiConnection(HttpState httpState, IPreferences preferences, IWritable logger, bool logVerboseMessages, IOpenApiSearchPathsProvider? openApiSearchPaths = null)\n        {\n            _httpState = httpState ?? throw new ArgumentNullException(nameof(httpState));\n            _logger = logger ?? throw new ArgumentNullException(nameof(logger));\n            _logVerboseMessages = logVerboseMessages;\n            _searchPaths = openApiSearchPaths ?? new OpenApiSearchPathsProvider(preferences);\n        }\n\n        private async Task FindSwaggerDoc(HttpClient client, IEnumerable<string> swaggerSearchPaths, CancellationToken cancellationToken)\n        {\n            HashSet<Uri> checkedUris = new HashSet<Uri>();\n            List<Uri> baseUrisToCheck = new List<Uri>();\n            if (HasRootUri)\n            {\n                baseUrisToCheck.Add(RootUri!);\n            }\n            if (HasBaseUri)\n            {\n                baseUrisToCheck.Add(BaseUri!);\n            }\n\n            foreach (Uri baseUriToCheck in baseUrisToCheck)\n            {\n                foreach (string swaggerSearchPath in swaggerSearchPaths)\n                {\n                    if (Uri.TryCreate(baseUriToCheck, swaggerSearchPath, out Uri? swaggerUri) && !checkedUris.Contains(swaggerUri))\n                    {\n                        string? document = await GetSwaggerDocAsync(client, swaggerUri, cancellationToken);\n                        if (document is not null)\n                        {\n                            SwaggerUri = swaggerUri;\n                            SwaggerDocument = document;\n                            return;\n                        }\n                        checkedUris.Add(swaggerUri);\n                    }\n                }\n            }\n        }\n\n        private async Task<string?> GetSwaggerDocAsync(HttpClient client, Uri uri, CancellationToken cancellationToken)\n        {\n            try\n            {\n                WriteVerbose(string.Format(Resources.Strings.ApiConnection_Logging_Checking, uri));\n                HttpResponseMessage? response = await client.GetAsync(uri, cancellationToken).ConfigureAwait(false);\n                if (cancellationToken.IsCancellationRequested)\n                {\n                    _logger.WriteLine(Resources.Strings.ApiConnection_Logging_Cancelled.SetColor(_httpState.ErrorColor));\n                    return null;\n                }\n\n                if (response.IsSuccessStatusCode)\n                {\n                    WriteLineVerbose(Resources.Strings.ApiConnection_Logging_Found.SetColor(AllowedColors.BoldGreen));\n\n#if NET5_0_OR_GREATER\n                    string responseString = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);\n#else\n                    string responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);\n#endif\n\n                    WriteVerbose(Resources.Strings.ApiConnection_Logging_Parsing);\n                    ApiDefinitionReader reader = new ApiDefinitionReader();\n                    ApiDefinitionParseResult result = reader.CanHandle(responseString);\n                    if (result.Success)\n                    {\n                        if (result.ValidationMessages.Count == 0)\n                        {\n                            WriteLineVerbose(Resources.Strings.ApiConnection_Logging_Successful.SetColor(AllowedColors.BoldGreen));\n                        }\n                        else\n                        {\n                            WriteLineVerbose(Resources.Strings.ApiConnection_Logging_SuccessfulWithWarnings.SetColor(_httpState.WarningColor));\n                            foreach (string validationMessage in result.ValidationMessages)\n                            {\n                                WriteLineVerbose(validationMessage.SetColor(_httpState.WarningColor));\n                            }\n                        }\n                        return responseString;\n                    }\n                    else\n                    {\n                        WriteLineVerbose(Resources.Strings.ApiConnection_Logging_Failed.SetColor(_httpState.ErrorColor));\n                        return null;\n                    }\n                }\n                else\n                {\n                    int statusCode = (int)response.StatusCode;\n                    string statusCodeDescription = response.StatusCode.ToString();\n                    WriteLineVerbose($\"{statusCode} {statusCodeDescription}\".SetColor(_httpState.ErrorColor));\n                    return null;\n                }\n            }\n            catch (Exception e)\n            {\n                WriteLineVerbose(e.Message.SetColor(_httpState.ErrorColor));\n                return null;\n            }\n            finally\n            {\n                WriteLineVerbose();\n            }\n        }\n\n        public void SetupApiDefinition(HttpState programState)\n        {\n            if (SwaggerDocument is not null && SwaggerUri is not null)\n            {\n                ApiDefinitionReader reader = new ApiDefinitionReader();\n                ApiDefinitionParseResult parseResult = reader.Read(SwaggerDocument, SwaggerUri);\n                if (parseResult.Success)\n                {\n                    programState.ApiDefinition = parseResult.ApiDefinition;\n                    if (programState.ApiDefinition is not null)\n                    {\n                        programState.SwaggerEndpoint = SwaggerUri;\n                    }\n                }\n            }\n        }\n\n        public async Task SetupHttpState(HttpState httpState, bool performAutoDetect, bool persistHeaders, bool persistPath, CancellationToken cancellationToken)\n        {\n            httpState.ResetState(persistHeaders, persistPath);\n\n            if (HasSwaggerUri)\n            {\n                SwaggerDocument = await GetSwaggerDocAsync(httpState.Client, SwaggerUri!, cancellationToken);\n            }\n            else if (performAutoDetect)\n            {\n                await FindSwaggerDoc(httpState.Client, _searchPaths.GetOpenApiSearchPaths(), cancellationToken);\n            }\n\n            if (HasSwaggerDocument)\n            {\n                SetupApiDefinition(httpState);\n            }\n\n            // If there's a base address in the api definition and there was no explicit base address, set the\n            // base address to the first one in the api definition\n            if (httpState.ApiDefinition?.BaseAddresses?.Any() == true && AllowBaseOverrideBySwagger)\n            {\n                httpState.BaseAddress = httpState.ApiDefinition.BaseAddresses[0].Url;\n            }\n            else if (HasBaseUri)\n            {\n                httpState.BaseAddress = BaseUri;\n            }\n        }\n\n\n\n        private void WriteVerbose(string s)\n        {\n            if (_logVerboseMessages)\n            {\n                _logger.Write(s);\n            }\n        }\n\n        private void WriteLineVerbose(string s)\n        {\n            if (_logVerboseMessages)\n            {\n                _logger.WriteLine(s);\n            }\n        }\n\n        private void WriteLineVerbose()\n        {\n            if (_logVerboseMessages)\n            {\n                _logger.WriteLine();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/AddQueryParamCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.Serialization.Formatters;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.HttpRepl.Telemetry.Events;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class AddQueryParamCommand : ICommand<HttpState, ICoreParseResult>\n    {\n        private const string CommandName = \"add\";\n        private const string SubCommand = \"query-param\";\n\n        private readonly ITelemetry _telemetry;\n\n        public string Name => \"addQueryParam\";\n\n        public AddQueryParamCommand(ITelemetry telemetry)\n        {\n            _telemetry = telemetry;\n        }\n\n        public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult) =>\n            parseResult.ContainsAtLeast(minimumLength: 3, CommandName, SubCommand)\n                ? (bool?)true\n                : null;\n\n        public Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            int sectionCount = parseResult.Sections.Count;\n            bool isValueEmpty;\n\n            if(sectionCount % 2 == 0)\n            {               \n                for(int i = 2; i < sectionCount; i+=2)\n                {\n                    if (i + 1 < sectionCount)\n                    {\n                        if (programState.QueryParam.ContainsKey(parseResult.Sections[i])){\n                            IEnumerable<string> updatedParams = programState.QueryParam[parseResult.Sections[i]].Append(parseResult.Sections[i + 1]);\n                            programState.QueryParam[parseResult.Sections[i]] = updatedParams;\n                        } else\n                        {\n                            programState.QueryParam[parseResult.Sections[i]] = Enumerable.Repeat(parseResult.Sections[i + 1], 1);\n                        }\n                            \n                    }             \n                }\n                isValueEmpty = false;\n            } else\n            {\n                isValueEmpty = true;\n                shellState.ConsoleManager.WriteLine($\"The add query-param command key: {parseResult.Sections[sectionCount - 1]} is missing a value. Please try again with a valid key value pair\");           \n            }\n            _telemetry.TrackEvent(new AddQueryParamEvent(parseResult.Sections[2], isValueEmpty));      \n\n            return Task.CompletedTask;\n        }\n\n        public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            if (parseResult.ContainsAtLeast(CommandName, SubCommand))\n            {\n                StringBuilder helpText = new StringBuilder();\n                helpText.Append(Strings.Usage.Bold());\n                helpText.AppendLine(\"add query-param {name} [value]\");\n                helpText.AppendLine();\n                helpText.AppendLine(Strings.AddQueryParamCommand_HelpDetails);\n                return helpText.ToString();\n            }\n\n            return null;\n        }\n\n        public string GetHelpSummary(IShellState shellState, HttpState programState) => Strings.AddQueryParamCommand_HelpSummary;\n\n        public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult) => null;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/BaseHttpCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Xml.Linq;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Formatting;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.HttpRepl.Suggestions;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.HttpRepl.Telemetry.Events;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Microsoft.Repl.Suggestions;\nusing Newtonsoft.Json.Linq;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public abstract class BaseHttpCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>\n    {\n        private const string HeaderOption = nameof(HeaderOption);\n        private const string ResponseHeadersFileOption = nameof(ResponseHeadersFileOption);\n        private const string ResponseBodyFileOption = nameof(ResponseBodyFileOption);\n        private const string BodyFileOption = nameof(BodyFileOption);\n        private const string NoBodyOption = nameof(NoBodyOption);\n        private const string NoFormattingOption = nameof(NoFormattingOption);\n        private const string StreamingOption = nameof(StreamingOption);\n        private const string BodyContentOption = nameof(BodyContentOption);\n        private static readonly char[] HeaderSeparatorChars = new[] { '=', ':' };\n        private static readonly Dictionary<string, string> FileExtensionLookup = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)\n        {\n            { \"application/json\", \".json\" },\n            { \"text/json\", \".json\" },\n            { \"application/xml\", \".xml\" },\n            { \"text/xml\", \".xml\" },\n        };\n\n        private CommandInputSpecification _inputSpec;\n\n        private readonly IFileSystem _fileSystem;\n        private readonly IPreferences _preferences;\n        private readonly ITelemetry _telemetry;\n\n        public override string Name => Verb;\n\n        protected abstract string Verb { get; }\n\n        protected abstract bool RequiresBody { get; }\n\n        protected BaseHttpCommand(IFileSystem fileSystem, IPreferences preferences, ITelemetry telemetry)\n        {\n            _fileSystem = fileSystem;\n            _preferences = preferences;\n            _telemetry = telemetry;\n        }\n\n        public override CommandInputSpecification InputSpec\n        {\n            get\n            {\n                if (_inputSpec != null)\n                {\n                    return _inputSpec;\n                }\n\n                CommandInputSpecificationBuilder builder = CommandInputSpecification.Create(Verb)\n                    .MaximumArgCount(1)\n                    .WithOption(new CommandOptionSpecification(HeaderOption, requiresValue: true, forms: new[] { \"--header\", \"-h\" }))\n                    .WithOption(new CommandOptionSpecification(ResponseHeadersFileOption, requiresValue: true, maximumOccurrences: 1, forms: new[] { \"--response:headers\", }))\n                    .WithOption(new CommandOptionSpecification(ResponseBodyFileOption, requiresValue: true, maximumOccurrences: 1, forms: new[] { \"--response:body\", }))\n                    .WithOption(new CommandOptionSpecification(NoFormattingOption, maximumOccurrences: 1, forms: new[] { \"--no-formatting\", \"-F\" }))\n                    .WithOption(new CommandOptionSpecification(StreamingOption, maximumOccurrences: 1, forms: new[] { \"--streaming\", \"-s\" }));\n\n                if (RequiresBody)\n                {\n                    builder = builder.WithOption(new CommandOptionSpecification(NoBodyOption, maximumOccurrences: 1, forms: \"--no-body\"))\n                        .WithOption(new CommandOptionSpecification(BodyFileOption, requiresValue: true, maximumOccurrences: 1, forms: new[] { \"--file\", \"-f\" }))\n                        .WithOption(new CommandOptionSpecification(BodyContentOption, requiresValue: true, maximumOccurrences: 1, forms: new[] { \"--content\", \"-c\" }));\n                }\n\n                _inputSpec = builder.Finish();\n                return _inputSpec;\n            }\n        }\n\n        protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            if (programState.BaseAddress == null && (commandInput.Arguments.Count == 0 || !Uri.TryCreate(commandInput.Arguments[0].Text, UriKind.Absolute, out _)))\n            {\n                shellState.ConsoleManager.Error.WriteLine(Strings.Error_NoBasePath.SetColor(programState.ErrorColor));\n                return;\n            }\n\n            SendTelemetry(commandInput);\n\n            if (programState.SwaggerEndpoint != null)\n            {\n                await CreateDirectoryStructureForSwaggerEndpointAsync(shellState, programState, cancellationToken).ConfigureAwait(false);\n            }\n\n            Dictionary<string, string> thisRequestHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n\n            foreach (InputElement header in commandInput.Options[HeaderOption])\n            {\n                int equalsIndex = header.Text.IndexOfAny(HeaderSeparatorChars);\n\n                if (equalsIndex < 0)\n                {\n                    shellState.ConsoleManager.Error.WriteLine(Strings.BaseHttpCommand_Error_HeaderFormatting.SetColor(programState.ErrorColor));\n                    return;\n                }\n\n                thisRequestHeaders[header.Text.Substring(0, equalsIndex)] = header.Text.Substring(equalsIndex + 1);\n            }\n\n            Uri effectivePath = programState.GetEffectivePath(commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty);\n            using (HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(Verb.ToUpperInvariant()), effectivePath))\n            {\n                if (RequiresBody)\n                {\n                    if (!HandleRequiresBody(commandInput, shellState, programState, request, thisRequestHeaders))\n                    {\n                        // HandleRequiresBody can fail if there is a problem with the specified file or the specified editor,\n                        // in which case we should bail out before trying to send the request.\n                        return;\n                    }\n                }\n\n                foreach (KeyValuePair<string, IEnumerable<string>> header in programState.Headers)\n                {\n                    // We only want to add headers that are not content headers\n                    if (!WellKnownHeaders.ContentHeaders.Contains(header.Key, StringComparer.OrdinalIgnoreCase))\n                    {\n                        request.Headers.TryAddWithoutValidation(header.Key, header.Value);\n                    }\n                }\n\n                foreach (KeyValuePair<string, string> header in thisRequestHeaders)\n                {\n                    // We only want to add headers that are not content headers\n                    if (!WellKnownHeaders.ContentHeaders.Contains(header.Key, StringComparer.OrdinalIgnoreCase))\n                    {\n                        request.Headers.TryAddWithoutValidation(header.Key, header.Value);\n                    }\n                }\n\n                InputElement responseHeadersFileOption = commandInput.Options[ResponseHeadersFileOption].Any() ? commandInput.Options[ResponseHeadersFileOption][0] : null;\n                InputElement responseBodyFileOption = commandInput.Options[ResponseBodyFileOption].Any() ? commandInput.Options[ResponseBodyFileOption][0] : null;\n\n                string headersTarget = responseHeadersFileOption?.Text;\n                string bodyTarget = responseBodyFileOption?.Text;\n\n                if (!string.IsNullOrWhiteSpace(headersTarget) &&\n                    string.Equals(headersTarget, bodyTarget, StringComparison.OrdinalIgnoreCase))\n                {\n                    shellState.ConsoleManager.Error.WriteLine(Strings.BaseHttpCommand_Error_SameBodyAndHeaderFileName.SetColor(programState.ErrorColor));\n                    return;\n                }\n\n                try\n                {\n                    HttpResponseMessage response = await programState.Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);\n                    await HandleResponseAsync(programState, commandInput, shellState.ConsoleManager, response, programState.EchoRequest, headersTarget, bodyTarget, cancellationToken).ConfigureAwait(false);\n                }\n                catch (HttpRequestException httpRequestException)\n                {\n                    shellState.ConsoleManager.Error.WriteLine(httpRequestException.Message.SetColor(programState.ErrorColor));\n                }\n                catch (OperationCanceledException)\n                {\n                    // We just want to eat this exception because the cancellation actually occurs for the entire command,\n                    // not just the HTTP Request. So the cancellation is handled further down the stack by inspecting\n                    // the CancellationToken.IsCancellationRequested property\n                }\n            }\n        }\n\n        private async Task CreateDirectoryStructureForSwaggerEndpointAsync(IShellState shellState, HttpState programState, CancellationToken cancellationToken)\n        {\n            string swaggerRequeryBehaviorSetting = _preferences.GetValue(WellKnownPreference.SwaggerRequeryBehavior, \"auto\");\n\n            if (swaggerRequeryBehaviorSetting.StartsWith(\"auto\", StringComparison.OrdinalIgnoreCase))\n            {\n                ApiConnection apiConnection = new ApiConnection(programState, _preferences, shellState.ConsoleManager, false)\n                {\n                    BaseUri = programState.BaseAddress,\n                    SwaggerUri = programState.SwaggerEndpoint,\n                    AllowBaseOverrideBySwagger = false\n                };\n                await apiConnection.SetupHttpState(programState, performAutoDetect: false, persistHeaders: true, persistPath: true, cancellationToken).ConfigureAwait(false);\n            }\n        }\n\n        private bool HandleRequiresBody(DefaultCommandInput<ICoreParseResult> commandInput,\n            IShellState shellState,\n            HttpState programState,\n            HttpRequestMessage request,\n            Dictionary<string, string> requestHeaders)\n        {\n            string filePath = null;\n            string bodyContent = null;\n            bool deleteFile = false;\n            bool noBody = commandInput.Options[NoBodyOption].Count > 0;\n\n            if (!requestHeaders.TryGetValue(\"content-type\", out string contentType) && programState.Headers.TryGetValue(\"content-type\", out IEnumerable<string> contentTypes))\n            {\n                contentType = contentTypes.FirstOrDefault();\n            }\n\n            if (!noBody)\n            {\n                if (string.IsNullOrEmpty(contentType))\n                {\n                    contentType = \"application/json\";\n                }\n\n                if (commandInput.Options[BodyFileOption].Count > 0)\n                {\n                    filePath = commandInput.Options[BodyFileOption][0].Text;\n\n                    if (!_fileSystem.FileExists(filePath))\n                    {\n                        shellState.ConsoleManager.Error.WriteLine(string.Format(Strings.BaseHttpCommand_Error_ContentFileDoesNotExist, filePath).SetColor(programState.ErrorColor));\n                        return false;\n                    }\n                }\n                else if (commandInput.Options[BodyContentOption].Count > 0)\n                {\n                    bodyContent = commandInput.Options[BodyContentOption][0].Text;\n                }\n                else\n                {\n                    string defaultEditorCommand = _preferences.GetValue(WellKnownPreference.DefaultEditorCommand, null);\n                    if (string.IsNullOrWhiteSpace(defaultEditorCommand))\n                    {\n                        shellState.ConsoleManager.Error.WriteLine(string.Format(Strings.BaseHttpCommand_Error_DefaultEditorNotConfigured, WellKnownPreference.DefaultEditorCommand).SetColor(programState.ErrorColor));\n                        return false;\n                    }\n                    else if (!_fileSystem.FileExists(defaultEditorCommand))\n                    {\n                        shellState.ConsoleManager.Error.WriteLine(string.Format(Strings.BaseHttpCommand_Error_DefaultEditorDoesNotExist, defaultEditorCommand).SetColor(programState.ErrorColor));\n                        return false;\n                    }\n\n                    deleteFile = true;\n                    filePath = _fileSystem.GetTempFileName(GetFileExtensionFromContentType(contentType));\n\n                    string exampleBody = GetExampleBody(commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty, ref contentType, Verb, programState);\n\n                    if (!string.IsNullOrEmpty(exampleBody))\n                    {\n                        _fileSystem.WriteAllTextToFile(filePath, exampleBody);\n                    }\n\n                    string defaultEditorArguments = _preferences.GetValue(WellKnownPreference.DefaultEditorArguments, null) ?? \"\";\n                    string original = defaultEditorArguments;\n                    string pathString = $\"\\\"{filePath}\\\"\";\n\n                    defaultEditorArguments = defaultEditorArguments.Replace(\"{filename}\", pathString, StringComparison.OrdinalIgnoreCase);\n\n                    if (string.Equals(defaultEditorArguments, original, StringComparison.Ordinal))\n                    {\n                        defaultEditorArguments = (defaultEditorArguments + \" \" + pathString).Trim();\n                    }\n\n                    ProcessStartInfo info = new ProcessStartInfo(defaultEditorCommand, defaultEditorArguments);\n\n                    Process.Start(info)?.WaitForExit();\n                }\n            }\n\n            if (string.IsNullOrEmpty(contentType))\n            {\n                contentType = \"application/json\";\n            }\n\n            byte[] data = noBody\n                ? Array.Empty<byte>()\n                : string.IsNullOrEmpty(bodyContent)\n                    ? _fileSystem.ReadAllBytesFromFile(filePath)\n                    : Encoding.UTF8.GetBytes(bodyContent);\n\n            HttpContent content = new ByteArrayContent(data);\n            content.Headers.ContentType = new MediaTypeHeaderValue(contentType);\n            request.Content = content;\n\n            if (deleteFile)\n            {\n                _fileSystem.DeleteFile(filePath);\n            }\n\n            AddHttpContentHeaders(content, programState, requestHeaders);\n\n            return true;\n        }\n\n        private static string GetFileExtensionFromContentType(string contentType)\n        {\n            if (FileExtensionLookup.TryGetValue(contentType, out string extension))\n            {\n                return extension;\n            }\n            return \".tmp\";\n        }\n\n        private static void AddHttpContentHeaders(HttpContent content, HttpState programState, Dictionary<string, string> requestHeaders)\n        {\n            foreach (KeyValuePair<string, IEnumerable<string>> header in programState.Headers)\n            {\n                // We only want to add content headers, except for Content-Type, which is handled elsewhere\n                if (WellKnownHeaders.ContentHeaders.Contains(header.Key, StringComparer.OrdinalIgnoreCase) &&\n                    !string.Equals(WellKnownHeaders.ContentType, header.Key, StringComparison.OrdinalIgnoreCase))\n                {\n                    content.Headers.TryAddWithoutValidation(header.Key, header.Value);\n                }\n            }\n\n            foreach (KeyValuePair<string, string> header in requestHeaders)\n            {\n                // We only want to add content headers, except for Content-Type, which is handled elsewhere\n                if (WellKnownHeaders.ContentHeaders.Contains(header.Key, StringComparer.OrdinalIgnoreCase) &&\n                    !string.Equals(WellKnownHeaders.ContentType, header.Key, StringComparison.OrdinalIgnoreCase))\n                {\n                    content.Headers.TryAddWithoutValidation(header.Key, header.Value);\n                }\n            }\n        }\n\n        private async Task HandleResponseAsync(HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, IConsoleManager consoleManager, HttpResponseMessage response, bool echoRequest, string headersTargetFile, string bodyTargetFile, CancellationToken cancellationToken)\n        {\n            string protocolInfo;\n\n            if (echoRequest)\n            {\n                RequestConfig requestConfig = new RequestConfig(_preferences);\n                string hostString = response.RequestMessage.RequestUri.Scheme + \"://\" + response.RequestMessage.RequestUri.Host + (!response.RequestMessage.RequestUri.IsDefaultPort ? \":\" + response.RequestMessage.RequestUri.Port : \"\");\n                await HandleEchoRequest(commandInput, consoleManager, programState, response, requestConfig, hostString, cancellationToken);\n\n                // Only need to write out this separator if we've echoed the request\n                consoleManager.WriteLine();\n                consoleManager.WriteLine($\"Response from {hostString}...\".SetColor(requestConfig.AddressColor));\n                consoleManager.WriteLine();\n            }\n\n            ResponseConfig responseConfig = new ResponseConfig(_preferences);\n\n            protocolInfo = $\"{\"HTTP\".SetColor(responseConfig.ProtocolNameColor)}{\"/\".SetColor(responseConfig.ProtocolSeparatorColor)}{response.Version.ToString().SetColor(responseConfig.ProtocolVersionColor)}\";\n            string status = ((int)response.StatusCode).ToString().SetColor(responseConfig.StatusCodeColor) + \" \" + response.ReasonPhrase.SetColor(responseConfig.StatusReasonPhraseColor);\n\n            consoleManager.WriteLine($\"{protocolInfo} {status}\");\n\n            IEnumerable<KeyValuePair<string, IEnumerable<string>>> responseHeaders = response.Headers;\n\n            if (response.Content != null)\n            {\n                responseHeaders = responseHeaders.Union(response.Content.Headers);\n            }\n\n            List<string> headerFileOutput = null;\n            List<string> bodyFileOutput = null;\n\n            if (headersTargetFile != null)\n            {\n                headerFileOutput = new List<string>();\n            }\n\n            foreach (KeyValuePair<string, IEnumerable<string>> header in responseHeaders.OrderBy(x => x.Key))\n            {\n                string headerKey = header.Key.SetColor(responseConfig.HeaderKeyColor);\n                string headerSep = \":\".SetColor(responseConfig.HeaderSeparatorColor);\n                string headerValue = string.Join(\";\".SetColor(responseConfig.HeaderValueSeparatorColor), header.Value.Select(x => x.Trim().SetColor(responseConfig.HeaderValueColor)));\n                consoleManager.WriteLine($\"{headerKey}{headerSep} {headerValue}\");\n                headerFileOutput?.Add($\"{header.Key}: {string.Join(\";\", header.Value.Select(x => x.Trim()))}\");\n            }\n\n            if (bodyTargetFile != null)\n            {\n                bodyFileOutput = new List<string>();\n            }\n\n            consoleManager.WriteLine();\n\n            if (response.Content != null)\n            {\n                await FormatBodyAsync(commandInput, programState, consoleManager, response.Content, bodyFileOutput, _preferences, cancellationToken).ConfigureAwait(false);\n            }\n\n            if (headersTargetFile != null && headerFileOutput != null)\n            {\n                _fileSystem.WriteAllLinesToFile(headersTargetFile, headerFileOutput);\n            }\n\n            if (bodyTargetFile != null && bodyFileOutput != null)\n            {\n                _fileSystem.WriteAllLinesToFile(bodyTargetFile, bodyFileOutput);\n            }\n\n            consoleManager.WriteLine();\n        }\n\n        private async Task HandleEchoRequest(DefaultCommandInput<ICoreParseResult> commandInput,\n            IConsoleManager consoleManager,\n            HttpState programState,\n            HttpResponseMessage response,\n            RequestConfig requestConfig,\n            string hostString,\n            CancellationToken cancellationToken)\n        {\n            consoleManager.WriteLine($\"Request to {hostString}...\".SetColor(requestConfig.AddressColor));\n            consoleManager.WriteLine();\n\n            string method = response.RequestMessage.Method.ToString().ToUpperInvariant().SetColor(requestConfig.MethodColor);\n            string pathAndQuery = response.RequestMessage.RequestUri.PathAndQuery.SetColor(requestConfig.AddressColor);\n            string protocolInfo = $\"{\"HTTP\".SetColor(requestConfig.ProtocolNameColor)}{\"/\".SetColor(requestConfig.ProtocolSeparatorColor)}{response.Version.ToString().SetColor(requestConfig.ProtocolVersionColor)}\";\n\n            consoleManager.WriteLine($\"{method} {pathAndQuery} {protocolInfo}\");\n            IEnumerable<KeyValuePair<string, IEnumerable<string>>> requestHeaders = response.RequestMessage.Headers;\n\n            if (response.RequestMessage.Content != null)\n            {\n                requestHeaders = requestHeaders.Union(response.RequestMessage.Content.Headers);\n            }\n\n            foreach (KeyValuePair<string, IEnumerable<string>> header in requestHeaders.OrderBy(x => x.Key))\n            {\n                string headerKey = header.Key.SetColor(requestConfig.HeaderKeyColor);\n                string headerSep = \":\".SetColor(requestConfig.HeaderSeparatorColor);\n                string headerValue = string.Join(\";\".SetColor(requestConfig.HeaderValueSeparatorColor), header.Value.Select(x => x.Trim().SetColor(requestConfig.HeaderValueColor)));\n                consoleManager.WriteLine($\"{headerKey}{headerSep} {headerValue}\");\n            }\n\n            consoleManager.WriteLine();\n\n            List<string> responseOutput = new List<string>();\n\n            if (response.RequestMessage.Content != null)\n            {\n                await FormatBodyAsync(commandInput, programState, consoleManager, response.RequestMessage.Content, responseOutput, _preferences, cancellationToken).ConfigureAwait(false);\n            }\n        }\n\n        private static async Task FormatBodyAsync(DefaultCommandInput<ICoreParseResult> commandInput, HttpState programState, IConsoleManager consoleManager, HttpContent content, List<string> bodyFileOutput, IPreferences preferences, CancellationToken cancellationToken)\n        {\n            if (commandInput.Options[StreamingOption].Count > 0)\n            {\n                Memory<char> buffer = new Memory<char>(new char[2048]);\n\n#if NET5_0_OR_GREATER\n                Stream s = await content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);\n#else\n                Stream s = await content.ReadAsStreamAsync().ConfigureAwait(false);\n#endif\n\n                using (StreamReader reader = new StreamReader(s))\n                {\n                    consoleManager.WriteLine(Resources.Strings.BaseHttpCommand_FormatBodyAsync_Streaming.SetColor(programState.WarningColor));\n\n                    while (!cancellationToken.IsCancellationRequested)\n                    {\n                        try\n                        {\n                            Task<int> readTask = reader.ReadAsync(buffer, cancellationToken).AsTask();\n                            if (await WaitForCompletionAsync(readTask, cancellationToken).ConfigureAwait(false))\n                            {\n                                if (readTask.Result == 0)\n                                {\n                                    break;\n                                }\n\n                                string str = new string(buffer.Span.Slice(0, readTask.Result));\n                                consoleManager.Write(str);\n                                bodyFileOutput.Add(str);\n                            }\n                            else\n                            {\n                                break;\n                            }\n                        }\n                        catch (OperationCanceledException)\n                        {\n                        }\n                    }\n                }\n\n                return;\n            }\n\n            await FormatResponseContentAsync(commandInput, consoleManager, content, bodyFileOutput, preferences);\n        }\n\n        private static async Task FormatResponseContentAsync(DefaultCommandInput<ICoreParseResult> commandInput,\n            IConsoleManager consoleManager,\n            HttpContent content,\n            List<string> bodyFileOutput,\n            IPreferences preferences)\n        {\n            string contentType = null;\n            if (content.Headers.TryGetValues(\"Content-Type\", out IEnumerable<string> contentTypeValues))\n            {\n                contentType = contentTypeValues.FirstOrDefault()?.Split(';').FirstOrDefault();\n            }\n\n            contentType = contentType?.ToUpperInvariant() ?? \"text/plain\";\n\n            if (commandInput.Options[NoFormattingOption].Count == 0)\n            {\n                if (contentType.EndsWith(\"/JSON\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"-JSON\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"+JSON\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"/JAVASCRIPT\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"-JAVASCRIPT\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"+JAVASCRIPT\", StringComparison.OrdinalIgnoreCase))\n                {\n                    if (await FormatJsonAsync(consoleManager, content, bodyFileOutput, preferences))\n                    {\n                        return;\n                    }\n                }\n                else if (contentType.EndsWith(\"/HTML\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"-HTML\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"+HTML\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"/XML\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"-XML\", StringComparison.OrdinalIgnoreCase)\n                    || contentType.EndsWith(\"+XML\", StringComparison.OrdinalIgnoreCase))\n                {\n                    if (await FormatXmlAsync(consoleManager, content, bodyFileOutput))\n                    {\n                        return;\n                    }\n                }\n            }\n\n            string responseContent = await content.ReadAsStringAsync().ConfigureAwait(false);\n            bodyFileOutput?.Add(responseContent);\n            consoleManager.WriteLine(responseContent);\n        }\n\n        private static async Task<bool> WaitForCompletionAsync(Task<int> readTask, CancellationToken cancellationToken)\n        {\n            while (!readTask.IsCompleted && !cancellationToken.IsCancellationRequested && !Console.KeyAvailable)\n            {\n                await Task.Delay(1, cancellationToken).ConfigureAwait(false);\n            }\n\n            if (Console.KeyAvailable)\n            {\n                Console.ReadKey(false);\n                return false;\n            }\n\n            return readTask.IsCompleted;\n        }\n\n        private static async Task<bool> FormatXmlAsync(IWritable consoleManager, HttpContent content, List<string> bodyFileOutput)\n        {\n            string responseContent = await content.ReadAsStringAsync().ConfigureAwait(false);\n            try\n            {\n                XDocument body = XDocument.Parse(responseContent);\n                consoleManager.WriteLine(body.ToString());\n                bodyFileOutput?.Add(body.ToString());\n                return true;\n            }\n            catch\n            {\n            }\n\n            return false;\n        }\n\n        private static async Task<bool> FormatJsonAsync(IWritable outputSink, HttpContent content, List<string> bodyFileOutput, IPreferences preferences)\n        {\n            string responseContent = await content.ReadAsStringAsync().ConfigureAwait(false);\n\n            try\n            {\n                JsonConfig config = new JsonConfig(preferences);\n                string formatted = JsonVisitor.FormatAndColorize(config, responseContent);\n                outputSink.WriteLine(formatted);\n                bodyFileOutput?.Add(JToken.Parse(responseContent).ToString());\n                return true;\n            }\n            catch\n            {\n            }\n\n            return false;\n        }\n\n        protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)\n        {\n            StringBuilder helpText = new StringBuilder();\n            helpText.Append(Strings.Usage.Bold());\n            helpText.AppendLine($\"{Verb.ToUpperInvariant()} [Options]\");\n            helpText.AppendLine();\n            helpText.AppendLine($\"Issues a {Verb.ToUpperInvariant()} request.\");\n\n            if (RequiresBody)\n            {\n                helpText.AppendLine(\"Your default editor will be opened with a sample body if no options are provided.\");\n            }\n\n            return helpText.ToString();\n        }\n\n        public override string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n#pragma warning disable CA1308 // Normalize strings to uppercase\n            return $\"{Verb.ToLowerInvariant()} - Issues a {Verb.ToUpperInvariant()} request\";\n#pragma warning restore CA1308 // Normalize strings to uppercase\n        }\n\n        protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)\n        {\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            List<string> results = new List<string>();\n\n            if (programState.Structure is object && programState.BaseAddress is object)\n            {\n                parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n                //If it's an absolute URI, nothing to suggest\n                if (Uri.TryCreate(parseResult.Sections[1], UriKind.Absolute, out Uri _))\n                {\n                    return null;\n                }\n\n                normalCompletionString = normalCompletionString ?? throw new ArgumentNullException(nameof(normalCompletionString));\n\n                string path = normalCompletionString.Replace('\\\\', '/');\n                int searchFrom = normalCompletionString.Length - 1;\n                int lastSlash = path.LastIndexOf('/', searchFrom);\n                string prefix;\n\n                if (lastSlash < 0)\n                {\n                    path = string.Empty;\n                    prefix = normalCompletionString;\n                }\n                else\n                {\n                    path = path.Substring(0, lastSlash + 1);\n                    prefix = normalCompletionString.Substring(lastSlash + 1);\n                }\n\n                IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);\n\n                foreach (string child in s.DirectoryNames)\n                {\n                    if (child.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))\n                    {\n                        results.Add(path + child);\n                    }\n                }\n            }\n\n            return results;\n        }\n\n        protected override IEnumerable<string> GetOptionValueCompletions(IShellState shellState, HttpState programState, string optionId, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, string normalizedCompletionText)\n        {\n            if (string.Equals(optionId, BodyFileOption, StringComparison.Ordinal) ||\n                string.Equals(optionId, ResponseBodyFileOption, StringComparison.OrdinalIgnoreCase) ||\n                string.Equals(optionId, ResponseHeadersFileOption, StringComparison.OrdinalIgnoreCase))\n            {\n                return FileSystemCompletion.GetCompletions(normalizedCompletionText);\n            }\n\n            if (string.Equals(optionId, HeaderOption, StringComparison.Ordinal))\n            {\n                commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n                normalizedCompletionText = normalizedCompletionText ?? throw new ArgumentNullException(nameof(normalizedCompletionText));\n\n                HashSet<string> alreadySpecifiedHeaders = new HashSet<string>(StringComparer.Ordinal);\n                IReadOnlyList<InputElement> options = commandInput.Options[HeaderOption];\n                for (int i = 0; i < options.Count; ++i)\n                {\n                    if (options[i] == commandInput.SelectedElement)\n                    {\n                        continue;\n                    }\n\n                    string elementText = options[i].Text;\n                    string existingHeaderName = elementText.Split(HeaderSeparatorChars)[0];\n                    alreadySpecifiedHeaders.Add(existingHeaderName);\n                }\n\n                //Check to see if the selected element is in a header name or value\n                int equalsIndex = normalizedCompletionText.IndexOfAny(HeaderSeparatorChars);\n                string path = commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty;\n\n                if (equalsIndex < 0)\n                {\n                    IEnumerable<string> headerNameOptions = HeaderCompletion.GetCompletions(alreadySpecifiedHeaders, normalizedCompletionText);\n\n                    List<string> allSuggestions = new List<string>();\n                    foreach (string suggestion in headerNameOptions.Select(x => x))\n                    {\n                        allSuggestions.Add(suggestion + \":\");\n\n                        IEnumerable<string> suggestions = HeaderCompletion.GetValueCompletions(Verb, path, suggestion, string.Empty, programState);\n\n                        if (suggestions != null)\n                        {\n                            foreach (string valueSuggestion in suggestions)\n                            {\n                                allSuggestions.Add(suggestion + \":\" + valueSuggestion);\n                            }\n                        }\n                    }\n\n                    return allSuggestions;\n                }\n                else\n                {\n                    //Didn't exit from the header name check, so must be a value\n                    string headerName = normalizedCompletionText.Substring(0, equalsIndex);\n                    IEnumerable<string> suggestions = HeaderCompletion.GetValueCompletions(Verb, path, headerName, normalizedCompletionText.Substring(equalsIndex + 1), programState);\n\n                    if (suggestions == null)\n                    {\n                        return null;\n                    }\n\n                    return suggestions.Select(x => normalizedCompletionText.Substring(0, equalsIndex + 1) + x);\n                }\n            }\n\n            return null;\n        }\n\n        private static string GetExampleBody(string path, ref string contentType, string method, HttpState httpState)\n        {\n            Uri effectivePath = httpState.GetEffectivePath(path);\n            string rootRelativePath = effectivePath.LocalPath.Substring(httpState.BaseAddress.LocalPath.Length).TrimStart('/');\n            IDirectoryStructure structure = httpState.Structure?.TraverseTo(rootRelativePath);\n            return structure?.RequestInfo?.GetRequestBodyForContentType(ref contentType, method);\n        }\n\n        private void SendTelemetry(DefaultCommandInput<ICoreParseResult> commandInput)\n        {\n            HttpCommandEvent httpCommandEvent = new HttpCommandEvent(\n                method:                         Verb.ToUpperInvariant(),\n                isPathSpecified:                commandInput.Arguments.Count > 0,\n                isHeaderSpecified:              commandInput.Options[HeaderOption].Any(),\n                isResponseHeadersFileSpecified: commandInput.Options[ResponseHeadersFileOption].Any(),\n                isResponseBodyFileSpecified:    commandInput.Options[ResponseBodyFileOption].Any(),\n                isNoFormattingSpecified:        commandInput.Options[NoFormattingOption].Any(),\n                isStreamingSpecified:           commandInput.Options[StreamingOption].Any(),\n                isNoBodySpecified:              RequiresBody && commandInput.Options[NoBodyOption].Any(),\n                isRequestBodyFileSpecified:     RequiresBody && commandInput.Options[BodyFileOption].Any(),\n                isRequestBodyContentSpecified:  RequiresBody && commandInput.Options[BodyContentOption].Any()\n            );\n\n            _telemetry.TrackEvent(httpCommandEvent);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/ChangeDirectoryCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.HttpRepl.Suggestions;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class ChangeDirectoryCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>\n    {\n        public override string Name => \"changeDirectory\";\n\n        protected override Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            if (commandInput.Arguments.Count == 0 || string.IsNullOrEmpty(commandInput.Arguments[0]?.Text))\n            {\n                shellState.ConsoleManager.WriteLine(programState.GetRelativePathString());\n            }\n            else\n            {\n                string[] parts = commandInput.Arguments[0].Text.Replace('\\\\', '/').Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);\n\n                if (commandInput.Arguments[0].Text.StartsWith(\"/\", StringComparison.Ordinal))\n                {\n                    programState.PathSections.Clear();\n                }\n\n                foreach (string part in parts)\n                {\n                    switch (part)\n                    {\n                        case \".\":\n                            break;\n                        case \"..\":\n                            if (programState.PathSections.Count > 0)\n                            {\n                                programState.PathSections.Pop();\n                            }\n                            break;\n                        default:\n                            programState.PathSections.Push(part);\n                            break;\n                    }\n                }\n\n                // If there's no directory structure, we can't traverse it to find the relevant\n                // metadata and display it. The command still succeeded as far as its impact on\n                // future commands, so we can safely just skip this part.\n                if (programState.Structure != null)\n                {\n                    IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse());\n\n                    string thisDirMethod = \"[]\";\n\n                    bool hasRequestMethods = s.RequestInfo?.Methods?.Count > 0;\n                    bool hasDirectoryNames = s.DirectoryNames?.Any() == true;\n\n                    // If there's no RequestInfo/Methods AND there's no (sub)DirectoryNames, we currently\n                    // assume this must be an auto-generated directory and not one from a swagger definition\n                    if (!hasRequestMethods && !hasDirectoryNames)\n                    {\n                        string warningMessage = string.Format(Resources.Strings.ChangeDirectoryCommand_Warning_UnknownEndpoint, programState.GetRelativePathString()).SetColor(programState.WarningColor);\n                        shellState.ConsoleManager.WriteLine(warningMessage);\n                    }\n                    else if (hasRequestMethods)\n                    {\n                        thisDirMethod = s.RequestInfo.GetDirectoryMethodListing();\n                    }\n\n                    shellState.ConsoleManager.WriteLine($\"{programState.GetRelativePathString()}    {thisDirMethod}\");\n                }\n            }\n\n            return Task.CompletedTask;\n        }\n\n        public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create(\"cd\")\n            .MaximumArgCount(1)\n            .Finish();\n\n        protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)\n        {\n            var help = new StringBuilder();\n            help.Append(Strings.Usage.Bold());\n            help.AppendLine(\"cd [directory]\");\n            help.AppendLine();\n            help.AppendLine(\"Prints the current directory if no argument is specified, otherwise changes to the specified directory\");\n\n            return help.ToString();\n        }\n\n        public override string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return Resources.Strings.ChangeDirectoryCommand_HelpSummary;\n        }\n\n        protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)\n        {\n            return ServerPathCompletion.GetCompletions(programState, normalCompletionString);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/ClearCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class ClearCommand : ICommand<object, ICoreParseResult>\n    {\n        private const string AlternateName = \"cls\";\n\n        public string Name => \"clear\";\n\n        public bool? CanHandle(IShellState shellState, object programState, ICoreParseResult parseResult)\n        {\n            return parseResult.ContainsExactly(Name) || parseResult.ContainsExactly(AlternateName)\n                ? (bool?) true\n                : null;\n        }\n\n        public Task ExecuteAsync(IShellState shellState, object programState, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            shellState.ConsoleManager.Clear();\n            shellState.CommandDispatcher.OnReady(shellState);\n            return Task.CompletedTask;\n        }\n\n        public string GetHelpDetails(IShellState shellState, object programState, ICoreParseResult parseResult)\n        {\n            if (parseResult.ContainsExactly(Name) || parseResult.ContainsExactly(AlternateName))\n            {\n                return \"Clears the shell\";\n            }\n\n            return null;\n        }\n\n        public string GetHelpSummary(IShellState shellState, object programState)\n        {\n            return Resources.Strings.ClearCommand_HelpSummary;\n        }\n\n        public IEnumerable<string> Suggest(IShellState shellState, object programState, ICoreParseResult parseResult)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            if (parseResult.SelectedSection == 0)\n            {\n                bool nameMatch = string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase);\n                bool alternateNameMatch = string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || AlternateName.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase);\n\n                if (nameMatch && alternateNameMatch)\n                {\n                    return new[] { Name, AlternateName };\n                }\n                else if (nameMatch)\n                {\n                    return new[] { Name };\n                }\n                else if (alternateNameMatch)\n                {\n                    return new[] { AlternateName };\n                }\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/ClearQueryParamCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.HttpRepl.Telemetry.Events;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class ClearQueryParamCommand : ICommand<HttpState, ICoreParseResult>\n    {\n        public string Name => \"clearQueryParam\";\n        private const string CommandName = \"clear\";\n        private const string SubCommand = \"query-param\";\n\n        public static string Description => Strings.ClearQueryParamCommand_HelpDetails;\n\n        private readonly ITelemetry _telemetry;\n\n        public ClearQueryParamCommand(ITelemetry telemetry) {\n            _telemetry = telemetry;\n        }\n\n        public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult) =>\n            parseResult.ContainsAtLeast(minimumLength: 2, CommandName, SubCommand)\n                ? (bool?)true\n                : null;\n\n        public Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            int sectionCount = parseResult.Sections.Count;\n            bool isValueEmpty;\n            if (sectionCount == 2)\n            {\n                programState.QueryParam.Clear();\n                isValueEmpty = true;\n            } else\n            {\n                isValueEmpty = false;\n            }\n\n            _telemetry.TrackEvent(new ClearQueryParamEvent(parseResult.Sections[1], isValueEmpty));\n            return Task.CompletedTask;\n        }\n\n        public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            if (parseResult.ContainsAtLeast(CommandName, SubCommand))\n            {\n                StringBuilder helpText = new StringBuilder();\n                helpText.Append(Strings.Usage.Bold());\n                helpText.AppendLine(\"clear query-param\");\n                helpText.AppendLine();\n                helpText.AppendLine(Strings.ClearQueryParamCommand_HelpDetails);\n                return helpText.ToString();\n            }\n\n            return null;\n        }\n\n        public string GetHelpSummary(IShellState shellState, HttpState programState) => Description;\n\n        public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult) => null;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/ConnectCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.HttpRepl.Telemetry.Events;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class ConnectCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>\n    {\n        private const string BaseAddressOption = nameof(BaseAddressOption);\n        private const string SwaggerAddressOption = nameof(SwaggerAddressOption);\n        private const string VerbosityOption = nameof(VerbosityOption);\n        private const string PersistHeadersOption = nameof(PersistHeadersOption);\n        private const string PersistPathOption = nameof(PersistPathOption);\n        public override string Name => \"connect\";\n        private const string WebApiDefaultPathSuffix = \"/swagger/\";\n\n        private readonly IPreferences _preferences;\n        private readonly ITelemetry _telemetry;\n\n        public ConnectCommand(IPreferences preferences, ITelemetry telemetry)\n        {\n            _preferences = preferences;\n            _telemetry = telemetry;\n        }\n\n        public override CommandInputSpecification InputSpec => CommandInputSpecification.Create(\"connect\")\n                                                                                        .MinimumArgCount(0)\n                                                                                        .MaximumArgCount(1)\n                                                                                        .WithOption(new CommandOptionSpecification(id: BaseAddressOption,\n                                                                                                                                   requiresValue: true,\n                                                                                                                                   minimumOccurrences: 0,\n                                                                                                                                   maximumOccurrences: 1,\n                                                                                                                                   forms: new[] { \"--base\", \"-b\" }))\n                                                                                        .WithOption(new CommandOptionSpecification(id: SwaggerAddressOption,\n                                                                                                                                   requiresValue: true,\n                                                                                                                                   minimumOccurrences: 0,\n                                                                                                                                   maximumOccurrences: 1,\n                                                                                                                                   forms: new[] { \"--openapi\", \"-o\",\n                                                                                                                                                  \"--swagger\", \"-s\" }))\n                                                                                        .WithOption(new CommandOptionSpecification(id: VerbosityOption,\n                                                                                                                                   acceptsValue: false,\n                                                                                                                                   minimumOccurrences: 0,\n                                                                                                                                   maximumOccurrences: 1,\n                                                                                                                                   forms: new[] { \"--verbose\", \"-v\" }))\n                                                                                        .WithOption(new CommandOptionSpecification(id: PersistHeadersOption,\n                                                                                                                                   maximumOccurrences: 1,\n                                                                                                                                   forms: new[] { \"--persist-headers\"}))\n                                                                                        .WithOption(new CommandOptionSpecification(id: PersistPathOption,\n                                                                                                                                   maximumOccurrences: 1,\n                                                                                                                                   forms: new[] { \"--persist-path\"}))\n                                                                                        .Finish();\n\n        public override string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return Resources.Strings.ConnectCommand_Description;\n        }\n\n        protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)\n        {\n            if (parseResult.ContainsAtLeast(Name))\n            {\n                StringBuilder helpText = new StringBuilder();\n                helpText.Append(Resources.Strings.Usage.Bold());\n                helpText.AppendLine(\"connect [rootAddress] [--base baseAddress] [--openapi openApiDescriptionAddress] [--verbose] [--persist-headers] [--persist-paths]\");\n                helpText.AppendLine();\n                helpText.AppendLine(Resources.Strings.ConnectCommand_HelpDetails_Line1);\n                helpText.AppendLine();\n                helpText.AppendLine(Resources.Strings.ConnectCommand_HelpDetails_Line2);\n                helpText.AppendLine(Resources.Strings.ConnectCommand_HelpDetails_Line3);\n                helpText.AppendLine(Resources.Strings.ConnectCommand_HelpDetails_Line4);\n                helpText.AppendLine(Resources.Strings.ConnectCommand_HelpDetails_Line5);\n                helpText.AppendLine(Resources.Strings.ConnectCommand_HelpDetails_Line6);\n                return helpText.ToString();\n            }\n            return null;\n        }\n\n        protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            string rootAddress = commandInput.Arguments.SingleOrDefault()?.Text?.EnsureTrailingSlash();\n            string baseAddress = GetBaseAddressFromCommand(commandInput)?.EnsureTrailingSlash();\n            string swaggerAddress = GetSwaggerAddressFromCommand(commandInput);\n            bool isVerbosityEnabled = GetOptionExistsFromCommand(commandInput, VerbosityOption);\n            bool persistHeaders = GetOptionExistsFromCommand(commandInput, PersistHeadersOption);\n            bool persistPath = GetOptionExistsFromCommand(commandInput, PersistPathOption);\n\n            ApiConnection connectionInfo = GetConnectionInfo(shellState, programState, rootAddress, baseAddress, swaggerAddress, _preferences, isVerbosityEnabled);\n\n            bool rootSpecified = !string.IsNullOrWhiteSpace(rootAddress);\n            bool baseSpecified = !string.IsNullOrWhiteSpace(baseAddress);\n            bool openApiSpecified = !string.IsNullOrWhiteSpace(swaggerAddress);\n\n            if (connectionInfo is null)\n            {\n                _telemetry.TrackEvent(new ConnectEvent(baseSpecified, rootSpecified, openApiSpecified, openApiFound: false));\n                return;\n            }\n\n            await connectionInfo.SetupHttpState(programState, performAutoDetect: true, persistHeaders, persistPath, cancellationToken);\n\n            bool openApiFound = connectionInfo?.HasSwaggerDocument == true;\n\n            _telemetry.TrackEvent(new ConnectEvent(baseSpecified, rootSpecified, openApiSpecified, openApiFound));\n\n            WriteStatus(shellState, programState);\n        }\n\n\n        private static void WriteStatus(IShellState shellState, HttpState programState)\n        {\n            if (programState.BaseAddress is null)\n            {\n                shellState.ConsoleManager.WriteLine(Resources.Strings.ConnectCommand_Status_NoBase.SetColor(programState.WarningColor));\n            }\n            else\n            {\n                shellState.ConsoleManager.WriteLine(string.Format(Resources.Strings.ConnectCommand_Status_Base, programState.BaseAddress));\n            }\n\n            if (programState.SwaggerEndpoint is null)\n            {\n                shellState.ConsoleManager.WriteLine(Resources.Strings.ConnectCommand_Status_NoSwagger.SetColor(programState.WarningColor));\n            }\n            else\n            {\n                shellState.ConsoleManager.WriteLine(string.Format(Resources.Strings.ConnectCommand_Status_Swagger, programState.SwaggerEndpoint));\n            }\n\n            // Always show help link after connecting\n            shellState.ConsoleManager.WriteLine(Resources.Strings.HelpCommand_Core_Details_Line2.Bold().Cyan());\n        }\n\n        private ApiConnection GetConnectionInfo(IShellState shellState, HttpState programState, string rootAddress, string baseAddress, string swaggerAddress, IPreferences preferences, bool isVerbosityEnabled)\n        {\n            rootAddress = rootAddress?.Trim();\n            baseAddress = baseAddress?.Trim();\n            swaggerAddress = swaggerAddress?.Trim();\n\n            if (string.IsNullOrWhiteSpace(rootAddress) && string.IsNullOrWhiteSpace(baseAddress) && string.IsNullOrWhiteSpace(swaggerAddress))\n            {\n                shellState.ConsoleManager.Error.WriteLine(Resources.Strings.ConnectCommand_Error_NothingSpecified);\n                return null;\n            }\n\n            if (!string.IsNullOrWhiteSpace(rootAddress) && !Uri.IsWellFormedUriString(rootAddress, UriKind.Absolute))\n            {\n                shellState.ConsoleManager.Error.WriteLine(Resources.Strings.ConnectCommand_Error_RootAddressNotValid);\n                return null;\n            }\n\n            // Even if verbosity is not enabled, we still want to be verbose about finding OpenAPI Descriptions\n            // if they specified one directly.\n            bool logVerboseMessages = isVerbosityEnabled || !string.IsNullOrWhiteSpace(swaggerAddress);\n\n            ApiConnection apiConnection = new ApiConnection(programState, preferences, shellState.ConsoleManager, logVerboseMessages);\n            if (!string.IsNullOrWhiteSpace(rootAddress))\n            {\n                // The `dotnet new webapi` template now has a default start url of `swagger`. Because\n                // the default Swashbuckle-generated OpenAPI description doesn't contain a Servers element\n                // this will put HttpRepl users into a pit of failure by having a base address of\n                // https://localhost:{port}/swagger/, even though the API is, by default, based at the root.\n                // Since it is unlikely a user would put their API inside the /swagger path, we will\n                // special-case this scenario and remove that from the url. We will give the user an escape\n                // hatch via the preference if they do put their API under that path.\n                if (rootAddress.EndsWith(WebApiDefaultPathSuffix, StringComparison.OrdinalIgnoreCase))\n                {\n                    WebApiF5FixEvent fixEvent;\n                    if (preferences.GetBoolValue(WellKnownPreference.ConnectCommandSkipRootFix))\n                    {\n                        fixEvent = new WebApiF5FixEvent(skippedByPreference: true);\n                    }\n                    else\n                    {\n                        rootAddress = rootAddress.Substring(0, rootAddress.Length - WebApiDefaultPathSuffix.Length);\n                        fixEvent = new WebApiF5FixEvent();\n                    }\n\n                    _telemetry.TrackEvent(fixEvent);\n                }\n\n                apiConnection.RootUri = new Uri(rootAddress, UriKind.Absolute);\n            }\n\n            if (!SetupBaseAddress(shellState, baseAddress, apiConnection) || !SetupSwaggerAddress(shellState, swaggerAddress, apiConnection))\n            {\n                return null;\n            }\n\n            apiConnection.AllowBaseOverrideBySwagger = !apiConnection.HasBaseUri;\n\n            if (apiConnection.HasRootUri && !apiConnection.HasBaseUri)\n            {\n                apiConnection.BaseUri = apiConnection.RootUri;\n            }\n\n            return apiConnection;\n        }\n\n        private static bool SetupSwaggerAddress(IShellState shellState, string swaggerAddress, ApiConnection connectionInfo)\n        {\n            if (!string.IsNullOrWhiteSpace(swaggerAddress))\n            {\n                if (!connectionInfo.HasRootUri && !Uri.IsWellFormedUriString(swaggerAddress, UriKind.Absolute))\n                {\n                    shellState.ConsoleManager.Error.WriteLine(Resources.Strings.ConnectCommand_Error_NoRootNoAbsoluteSwagger);\n                    return false;\n                }\n                else if (connectionInfo.HasRootUri && !Uri.IsWellFormedUriString(swaggerAddress, UriKind.RelativeOrAbsolute))\n                {\n                    shellState.ConsoleManager.Error.WriteLine(Resources.Strings.ConnectCommand_Error_InvalidSwagger);\n                    return false;\n                }\n\n                if (Uri.IsWellFormedUriString(swaggerAddress, UriKind.Absolute))\n                {\n                    connectionInfo.SwaggerUri = new Uri(swaggerAddress, UriKind.Absolute);\n                }\n                else if (Uri.IsWellFormedUriString(swaggerAddress, UriKind.Relative))\n                {\n                    connectionInfo.SwaggerUri = new Uri(connectionInfo.RootUri, swaggerAddress);\n                }\n            }\n\n            return true;\n        }\n\n        private static bool SetupBaseAddress(IShellState shellState, string baseAddress, ApiConnection connectionInfo)\n        {\n            if (!string.IsNullOrWhiteSpace(baseAddress))\n            {\n                if (!connectionInfo.HasRootUri && !Uri.IsWellFormedUriString(baseAddress, UriKind.Absolute))\n                {\n                    shellState.ConsoleManager.Error.WriteLine(Resources.Strings.ConnectCommand_Error_NoRootNoAbsoluteBase);\n                    return false;\n                }\n                else if (connectionInfo.HasRootUri && !Uri.IsWellFormedUriString(baseAddress, UriKind.RelativeOrAbsolute))\n                {\n                    shellState.ConsoleManager.Error.WriteLine(Resources.Strings.ConnectCommand_Error_InvalidBase);\n                    return false;\n                }\n\n                if (Uri.IsWellFormedUriString(baseAddress, UriKind.Absolute))\n                {\n                    connectionInfo.BaseUri = new Uri(baseAddress, UriKind.Absolute);\n                }\n                else if (Uri.IsWellFormedUriString(baseAddress, UriKind.Relative))\n                {\n                    connectionInfo.BaseUri = new Uri(connectionInfo.RootUri, baseAddress);\n                }\n            }\n\n            return true;\n        }\n\n        private static string GetBaseAddressFromCommand(DefaultCommandInput<ICoreParseResult> commandInput)\n        {\n            return GetOptionValueFromCommand(commandInput, BaseAddressOption);\n        }\n\n        private static string GetSwaggerAddressFromCommand(DefaultCommandInput<ICoreParseResult> commandInput)\n        {\n            return GetOptionValueFromCommand(commandInput, SwaggerAddressOption);\n        }\n\n        private static string GetOptionValueFromCommand(DefaultCommandInput<ICoreParseResult> commandInput, string optionId)\n        {\n            if (commandInput.Options.TryGetValue(optionId, out IReadOnlyList<InputElement> inputElements))\n            {\n                InputElement inputElement = inputElements.Any() ? inputElements[0] : null;\n                return inputElement?.Text;\n            }\n\n            return null;\n        }\n\n        private static bool GetOptionExistsFromCommand(DefaultCommandInput<ICoreParseResult> commandInput, string optionId)\n        {\n            return commandInput.Options[optionId].Count > 0;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/DeleteCommand.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class DeleteCommand : BaseHttpCommand\n    {\n        public DeleteCommand(IFileSystem fileSystem, IPreferences preferences, ITelemetry telemetry) : base(fileSystem, preferences, telemetry) { }\n\n        protected override string Verb => \"delete\";\n\n        protected override bool RequiresBody => false;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/EchoCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class EchoCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>\n    {\n        public override string Name => \"echo\";\n\n        private readonly HashSet<string> _allowedModes = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {\"on\", \"off\"};\n\n        protected override bool CanHandle(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput)\n        {\n            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            if (commandInput.Arguments.Count == 0 || !_allowedModes.Contains(commandInput.Arguments[0]?.Text))\n            {\n                shellState.ConsoleManager.Error.WriteLine(Resources.Strings.EchoCommand_Error_AllowedModes.SetColor(programState.ErrorColor));\n                return false;\n            }\n\n            return true;\n        }\n\n        protected override Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            bool turnOn = string.Equals(commandInput.Arguments[0].Text, \"on\", StringComparison.OrdinalIgnoreCase);\n            programState.EchoRequest = turnOn;\n\n            shellState.ConsoleManager.WriteLine(\"Request echoing is \" + (turnOn ? \"on\" : \"off\"));\n            return Task.CompletedTask;\n        }\n\n        public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create(\"echo\").ExactArgCount(1).Finish();\n\n        protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)\n        {\n            var helpText = new StringBuilder();\n            helpText.Append(Resources.Strings.Usage.Bold());\n            helpText.AppendLine($\"echo [on|off]\");\n            helpText.AppendLine();\n            helpText.AppendLine($\"Turns request echoing on or off. When request echoing is on we will display a text representation of requests made by the CLI.\");\n            return helpText.ToString();\n        }\n\n        public override string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return Resources.Strings.EchoCommand_HelpSummary;\n        }\n\n        protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)\n        {\n            List<string> result = _allowedModes.Where(x => x.StartsWith(normalCompletionString, StringComparison.OrdinalIgnoreCase)).ToList();\n            return result.Count > 0 ? result : null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/ExitCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class ExitCommand : CommandWithStructuredInputBase<object, ICoreParseResult>\n    {\n        public override string Name => \"exit\";\n\n        protected override Task ExecuteAsync(IShellState shellState, object programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            shellState.IsExiting = true;\n            return Task.CompletedTask;\n        }\n\n        public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create(\"exit\").ExactArgCount(0).Finish();\n\n        protected override string GetHelpDetails(IShellState shellState, object programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)\n        {\n            var helpText = new StringBuilder();\n            helpText.Append(Resources.Strings.Usage.Bold());\n            helpText.AppendLine($\"exit\");\n            helpText.AppendLine();\n            helpText.AppendLine($\"Exits the shell\");\n            return helpText.ToString();\n        }\n\n        public override string GetHelpSummary(IShellState shellState, object programState)\n        {\n            return Resources.Strings.ExitCommand_HelpSummary;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/Formatter.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.txt file in the project root for more information.\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class Formatter\n    {\n        private int _prefix;\n        private int _maxDepth;\n\n        public void RegisterEntry(int prefixLength, int depth)\n        {\n            if (depth > _maxDepth)\n            {\n                _maxDepth = depth;\n            }\n\n            if (prefixLength > _prefix)\n            {\n                _prefix = prefixLength;\n            }\n        }\n\n        public string Format(string prefix, string entry, int level)\n        {\n            string indent = \"\".PadRight(level * 4);\n            return (indent + prefix).PadRight(_prefix + 3 + _maxDepth * 4) + entry;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/GetCommand.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class GetCommand : BaseHttpCommand\n    {\n        public GetCommand(IFileSystem fileSystem, IPreferences preferences, ITelemetry telemetry) : base(fileSystem, preferences, telemetry) { }\n\n        protected override string Verb => \"get\";\n\n        protected override bool RequiresBody => false;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/HeadCommand.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class HeadCommand : BaseHttpCommand\n    {\n        public HeadCommand(IFileSystem fileSystem, IPreferences preferences, ITelemetry telemetry) : base(fileSystem, preferences, telemetry) { }\n\n        protected override string Verb => \"head\";\n\n        protected override bool RequiresBody => false;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/HelpCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.HttpRepl.Suggestions;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class HelpCommand : ICommand<HttpState, ICoreParseResult>\n    {\n        public string Name => \"help\";\n\n        public HelpCommand()\n        {\n\n        }\n\n        public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            return parseResult.ContainsAtLeast(Name)\n                ? (bool?)true\n                : null;\n        }\n\n        public Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            if (shellState.CommandDispatcher is ICommandDispatcher<HttpState, ICoreParseResult> dispatcher)\n            {\n                if (parseResult.Sections.Count == 1)\n                {\n                    CoreGetHelp(shellState, dispatcher, programState);\n                }\n                else\n                {\n                    bool anyHelp = false;\n                    StringBuilder output = new StringBuilder();\n\n                    if (parseResult.Slice(1) is ICoreParseResult continuationParseResult)\n                    {\n                        foreach (ICommand<HttpState, ICoreParseResult> command in dispatcher.Commands)\n                        {\n                            string help = command.GetHelpDetails(shellState, programState, continuationParseResult);\n\n                            if (!string.IsNullOrEmpty(help))\n                            {\n                                anyHelp = true;\n                                output.AppendLine();\n                                output.AppendLine(help);\n\n                                CommandWithStructuredInputBase<HttpState, ICoreParseResult> structuredCommand = GetStructuredCommand(command);\n                                if (structuredCommand is not null && structuredCommand.InputSpec.Options.Any())\n                                {\n                                    output.AppendLine();\n                                    output.AppendLine(Strings.Options.Bold());\n                                    foreach (CommandOptionSpecification option in structuredCommand.InputSpec.Options)\n                                    {\n                                        string optionText = string.Empty;\n                                        foreach (string form in option.Forms)\n                                        {\n                                            if (!string.IsNullOrEmpty(optionText))\n                                            {\n                                                optionText += \"|\";\n                                            }\n                                            optionText += form;\n                                        }\n                                        output.AppendLine($\"    {optionText}\");\n                                    }\n                                }\n\n                                break;\n                            }\n                        }\n                    }\n\n                    if (!anyHelp)\n                    {\n                        output.AppendLine(Strings.HelpCommand_Error_UnableToLocateHelpInfo);\n                    }\n\n                    shellState.ConsoleManager.Write(output.ToString());\n                }\n            }\n\n            return Task.CompletedTask;\n        }\n\n        public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            if (parseResult.ContainsAtLeast(Name))\n            {\n                if (parseResult.Sections.Count > 1)\n                {\n                    return \"Gets help about \" + parseResult.Slice(1).CommandText;\n                }\n                else\n                {\n                    return \"Gets help\";\n                }\n            }\n\n            return null;\n        }\n\n        public string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return \"help - Gets help\";\n        }\n\n        public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            if (parseResult.SelectedSection == 0 &&\n                (string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))\n            {\n                return new[] { Name };\n            }\n            else if (parseResult.ContainsAtLeast(minimumLength: 2, Name))\n            {\n                if (shellState.CommandDispatcher is ICommandDispatcher<HttpState, ICoreParseResult> dispatcher\n                    && parseResult.Slice(1) is ICoreParseResult continuationParseResult)\n                {\n                    HashSet<string> suggestions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\n\n                    foreach (ICommand<HttpState, ICoreParseResult> command in dispatcher.Commands)\n                    {\n                        IEnumerable<string> commandSuggestions = command.Suggest(shellState, programState, continuationParseResult);\n\n                        if (commandSuggestions != null)\n                        {\n                            suggestions.UnionWith(commandSuggestions);\n                        }\n                    }\n\n                    if (continuationParseResult.SelectedSection == 0)\n                    {\n                        string normalizedCompletionText = continuationParseResult.Sections[0].Substring(0, continuationParseResult.CaretPositionWithinSelectedSection);\n                        IEnumerable<string> completions = ServerPathCompletion.GetCompletions(programState, normalizedCompletionText);\n\n                        if (completions != null)\n                        {\n                            suggestions.UnionWith(completions);\n                        }\n                    }\n\n                    return suggestions.OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList();\n                }\n            }\n\n            return null;\n        }\n\n        public static void CoreGetHelp(IShellState shellState, ICommandDispatcher<HttpState, ICoreParseResult> dispatcher, HttpState programState)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));\n\n            const int navCommandColumn = -15;\n            StringBuilder output = new StringBuilder();\n\n            output.AppendLine();\n            output.AppendLine(Strings.HelpCommand_Core_SetupCommands.Bold().Cyan());\n            output.AppendLine(Strings.HelpCommand_Core_SetupCommands_Description);\n            output.AppendLine();\n            output.AppendLine($\"{\"connect\",navCommandColumn}{GetCommand<ConnectCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"set header\",navCommandColumn}{GetCommand<SetHeaderCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"add query-param\",navCommandColumn}{GetCommand<AddQueryParamCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"clear query-param\",navCommandColumn}{GetCommand<ClearQueryParamCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine();\n            output.AppendLine(Strings.HelpCommand_Core_HttpCommands.Bold().Cyan());\n            output.AppendLine(Strings.HelpCommand_Core_HttpCommands_Description);\n            output.AppendLine();\n            output.AppendLine($\"{\"GET\",navCommandColumn}{GetCommand<GetCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"POST\",navCommandColumn}{GetCommand<PostCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"PUT\",navCommandColumn}{GetCommand<PutCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"DELETE\",navCommandColumn}{GetCommand<DeleteCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"PATCH\",navCommandColumn}{GetCommand<PatchCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"HEAD\",navCommandColumn}{GetCommand<HeadCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"OPTIONS\",navCommandColumn}{GetCommand<OptionsCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n\n            output.AppendLine();\n            output.AppendLine(Strings.HelpCommand_Core_NavigationCommands.Bold().Cyan());\n            output.AppendLine(Strings.HelpCommand_Core_NavigationCommands_Description);\n            output.AppendLine();\n\n            output.AppendLine($\"{\"ls\",navCommandColumn}{GetCommand<ListCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"cd\",navCommandColumn}{GetCommand<ChangeDirectoryCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n\n            output.AppendLine();\n            output.AppendLine(Strings.HelpCommand_Core_ShellCommands.Bold().Cyan());\n            output.AppendLine(Strings.HelpCommand_Core_ShellCommands_Description);\n            output.AppendLine();\n\n            output.AppendLine($\"{\"clear\",navCommandColumn}{GetCommand<ClearCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"echo [on/off]\",navCommandColumn}{GetCommand<EchoCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"exit\",navCommandColumn}{GetCommand<ExitCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n\n            output.AppendLine();\n            output.AppendLine(Strings.HelpCommand_Core_CustomizationCommands.Bold().Cyan());\n            output.AppendLine(Strings.HelpCommand_Core_CustomizationCommands_Description);\n            output.AppendLine();\n\n            output.AppendLine($\"{\"pref [get/set]\",navCommandColumn}{GetCommand<PrefCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"run\",navCommandColumn}{GetCommand<RunCommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine($\"{\"ui\",navCommandColumn}{GetCommand<UICommand>(dispatcher).GetHelpSummary(shellState, programState)}\");\n            output.AppendLine();\n            output.AppendLine(Strings.HelpCommand_Core_Details_Line1.Bold().Cyan());\n            output.AppendLine(Strings.HelpCommand_Core_Details_Line2.Bold().Cyan());\n            output.AppendLine();\n\n            shellState.ConsoleManager.Write(output.ToString());\n        }\n\n        private static CommandWithStructuredInputBase<HttpState, ICoreParseResult> GetStructuredCommand(ICommand<HttpState, ICoreParseResult> rawCommand)\n        {\n            return rawCommand switch\n            {\n                CommandWithStructuredInputBase<HttpState, ICoreParseResult> structuredCommand => structuredCommand,\n                TelemetryCommandWrapper telemetryWrapper when telemetryWrapper.Command is CommandWithStructuredInputBase<HttpState, ICoreParseResult> structuredCommand => structuredCommand,\n                _ => null\n            };\n        }\n\n        private static ICommand<HttpState, ICoreParseResult> GetCommand<T>(ICommandDispatcher<HttpState, ICoreParseResult> dispatcher) where T : ICommand<HttpState, ICoreParseResult>\n        {\n            foreach (ICommand<HttpState, ICoreParseResult> command in dispatcher.Commands)\n            {\n                switch (command)\n                {\n                    case T directMatch:\n                        return directMatch;\n                    case TelemetryCommandWrapper telemetryWrapper when telemetryWrapper.Command?.GetType() == typeof(T):\n                        return telemetryWrapper;\n                }\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/ListCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class ListCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>\n    {\n        private const string RecursiveOption = nameof(RecursiveOption);\n        private const string VerboseOption = nameof(VerboseOption);\n\n        private readonly IPreferences _preferences;\n\n        public override string Name => \"list\";\n\n        public ListCommand(IPreferences preferences)\n        {\n            _preferences = preferences;\n        }\n\n        protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n            if (programState.SwaggerEndpoint != null)\n            {\n                string swaggerRequeryBehaviorSetting = _preferences.GetValue(WellKnownPreference.SwaggerRequeryBehavior, \"auto\");\n\n                if (swaggerRequeryBehaviorSetting.StartsWith(\"auto\", StringComparison.OrdinalIgnoreCase))\n                {\n                    ApiConnection apiConnection = new ApiConnection(programState, _preferences, shellState.ConsoleManager, logVerboseMessages: false)\n                    {\n                        BaseUri = programState.BaseAddress,\n                        SwaggerUri = programState.SwaggerEndpoint,\n                        AllowBaseOverrideBySwagger = false\n                    };\n                    await apiConnection.SetupHttpState(programState, performAutoDetect: false, persistHeaders: true, persistPath: true, cancellationToken).ConfigureAwait(false);\n                }\n            }\n\n            if (programState.BaseAddress is null)\n            {\n                shellState.ConsoleManager.WriteLine(Resources.Strings.ListCommand_Error_NoBaseAddress.SetColor(programState.WarningColor));\n                return;\n            }\n\n            if (programState.SwaggerEndpoint is null || programState.Structure is null)\n            {\n                shellState.ConsoleManager.WriteLine(Resources.Strings.ListCommand_Error_NoDirectoryStructure.SetColor(programState.WarningColor));\n                return;\n            }\n\n            string path = commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty;\n\n            //If it's an absolute URI, nothing to suggest\n            if (Uri.TryCreate(path, UriKind.Absolute, out Uri _))\n            {\n                return;\n            }\n\n            IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);\n\n            string thisDirMethod = s.RequestInfo.GetDirectoryMethodListing();\n\n            List<TreeNode> roots = new List<TreeNode>();\n            Formatter formatter = new Formatter();\n\n            roots.Add(new TreeNode(formatter, \".\", thisDirMethod));\n\n            if (s.Parent != null)\n            {\n                string parentDirMethod = s.Parent.RequestInfo.GetDirectoryMethodListing();\n\n                roots.Add(new TreeNode(formatter, \"..\", parentDirMethod));\n            }\n\n            int recursionDepth = 1;\n\n            if (commandInput.Options[RecursiveOption].Count > 0)\n            {\n                if (string.IsNullOrEmpty(commandInput.Options[RecursiveOption][0]?.Text))\n                {\n                    recursionDepth = int.MaxValue;\n                }\n                else if (int.TryParse(commandInput.Options[RecursiveOption][0].Text, NumberStyles.Integer, CultureInfo.InvariantCulture, out int rd) && rd > 1)\n                {\n                    recursionDepth = rd;\n                }\n            }\n\n            foreach (string child in s.DirectoryNames)\n            {\n                IDirectoryStructure dir = s.GetChildDirectory(child);\n\n                string methods = dir.RequestInfo.GetDirectoryMethodListing();\n\n                TreeNode dirNode = new TreeNode(formatter, child, methods);\n                roots.Add(dirNode);\n                Recurse(dirNode, dir, recursionDepth - 1);\n            }\n\n            foreach (TreeNode node in roots)\n            {\n                shellState.ConsoleManager.WriteLine(node.ToString());\n            }\n\n            bool hasVerboseOption = commandInput.Options[VerboseOption].Count > 0;\n            bool hasRequestMethods = s.RequestInfo?.Methods?.Count > 0;\n\n            if (hasVerboseOption && hasRequestMethods)\n            {\n                shellState.ConsoleManager.WriteLine();\n                shellState.ConsoleManager.WriteLine(Resources.Strings.ListCommand_AvailableMethods);\n\n                foreach (string method in s.RequestInfo.Methods)\n                {\n                    shellState.ConsoleManager.WriteLine(\"  \" + method.ToUpperInvariant());\n                    IReadOnlyList<string> accepts = s.RequestInfo.ContentTypesByMethod[method];\n                    string acceptsString = string.Join(\", \", accepts.Where(x => !string.IsNullOrEmpty(x)));\n                    if (!string.IsNullOrEmpty(acceptsString))\n                    {\n                        shellState.ConsoleManager.WriteLine($\"    {Resources.Strings.ListCommand_Accepts} \" + acceptsString);\n                    }\n                }\n            }\n        }\n\n        private static void Recurse(TreeNode parentNode, IDirectoryStructure parent, int remainingDepth)\n        {\n            if (remainingDepth <= 0)\n            {\n                return;\n            }\n\n            foreach (string child in parent.DirectoryNames)\n            {\n                IDirectoryStructure dir = parent.GetChildDirectory(child);\n\n                string methods = dir.RequestInfo?.GetDirectoryMethodListing();\n\n                TreeNode node = parentNode.AddChild(child, methods);\n                Recurse(node, dir, remainingDepth - 1);\n            }\n        }\n\n\n\n        public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create(\"ls\").AlternateName(\"dir\")\n            .MaximumArgCount(1)\n            .WithOption(new CommandOptionSpecification(RecursiveOption, acceptsValue: true, maximumOccurrences: 1, forms: new[] {\"-r\", \"--recursive\"}))\n            .WithOption(new CommandOptionSpecification(VerboseOption, acceptsValue: false, maximumOccurrences: 1, forms: new[] { \"-v\", \"--verbose\"}))\n            .Finish();\n\n        protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)\n        {\n            var helpText = new StringBuilder();\n            helpText.Append(Resources.Strings.Usage.Bold());\n            helpText.AppendLine($\"ls [Options]\");\n            helpText.AppendLine();\n            helpText.AppendLine($\"Displays the known routes at the current location. Requires a Swagger document to be set.\");\n            return helpText.ToString();\n        }\n\n        public override string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return Resources.Strings.ListCommand_HelpSummary;\n        }\n\n        protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)\n        {\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            if (programState.Structure == null || programState.BaseAddress == null)\n            {\n                return null;\n            }\n\n            //If it's an absolute URI, nothing to suggest\n            if (Uri.TryCreate(normalCompletionString, UriKind.Absolute, out Uri _))\n            {\n                return null;\n            }\n\n            normalCompletionString = normalCompletionString ?? throw new ArgumentNullException(nameof(normalCompletionString));\n\n            string path = normalCompletionString.Replace('\\\\', '/');\n            int searchFrom = normalCompletionString.Length - 1;\n            int lastSlash = path.LastIndexOf('/', searchFrom);\n            string prefix;\n\n            if (lastSlash < 0)\n            {\n                path = string.Empty;\n                prefix = normalCompletionString;\n            }\n            else\n            {\n                path = path.Substring(0, lastSlash + 1);\n                prefix = normalCompletionString.Substring(lastSlash + 1);\n            }\n\n            IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);\n\n            List<string> results = new List<string>();\n\n            foreach (string child in s.DirectoryNames)\n            {\n                if (child.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))\n                {\n                    results.Add(path + child);\n                }\n            }\n\n            return results;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/OptionsCommand.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class OptionsCommand : BaseHttpCommand\n    {\n        public OptionsCommand(IFileSystem fileSystem, IPreferences preferences, ITelemetry telemetry) : base(fileSystem, preferences, telemetry) { }\n\n        protected override string Verb => \"options\";\n\n        protected override bool RequiresBody => false;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/PatchCommand.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class PatchCommand : BaseHttpCommand\n    {\n        public PatchCommand(IFileSystem fileSystem, IPreferences preferences, ITelemetry telemetry) : base(fileSystem, preferences, telemetry) { }\n\n        protected override string Verb => \"patch\";\n\n        protected override bool RequiresBody => true;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/PostCommand.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class PostCommand : BaseHttpCommand\n    {\n        public PostCommand(IFileSystem fileSystem, IPreferences preferences, ITelemetry telemetry) : base(fileSystem, preferences, telemetry) { }\n\n        protected override string Verb => \"post\";\n\n        protected override bool RequiresBody => true;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/PrefCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.HttpRepl.Telemetry.Events;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class PrefCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>\n    {\n        private const string _CommandSyntax = \"pref [get/set] {setting} [{value}]\";\n        private const string _GetCommandSyntax = \"pref get [{setting}]\";\n        private const string _SetCommandSyntax = \"pref set {setting} [{value}]\";\n        private readonly HashSet<string> _allowedSubcommands = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {\"get\", \"set\"};\n        private readonly IPreferences _preferences;\n        private readonly ITelemetry _telemetry;\n\n        public override string Name => \"pref\";\n\n        public PrefCommand(IPreferences preferences, ITelemetry telemetry)\n        {\n            _preferences = preferences;\n            _telemetry = telemetry;\n        }\n\n        public override string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return string.Format(Resources.Strings.PrefCommand_HelpSummary, _CommandSyntax);\n        }\n\n        protected override bool CanHandle(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput)\n        {\n            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            if (commandInput.Arguments.Count == 0 || !_allowedSubcommands.Contains(commandInput.Arguments[0]?.Text))\n            {\n                shellState.ConsoleManager.Error.WriteLine(Resources.Strings.PrefCommand_Error_NoGetOrSet);\n                return false;\n            }\n\n            if (!string.Equals(\"get\", commandInput.Arguments[0].Text, StringComparison.OrdinalIgnoreCase) && (commandInput.Arguments.Count < 2 || string.IsNullOrEmpty(commandInput.Arguments[1]?.Text)))\n            {\n                shellState.ConsoleManager.Error.WriteLine(Resources.Strings.PrefCommand_Error_NoPreferenceName);\n                return false;\n            }\n\n            return true;\n        }\n\n        protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)\n        {\n            var helpText = new StringBuilder();\n            helpText.Append(Resources.Strings.Help_Usage.Bold());\n\n            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n            if (commandInput.Arguments.Count == 0 || !_allowedSubcommands.Contains(commandInput.Arguments[0]?.Text))\n            {\n                helpText.AppendFormat(Resources.Strings.PrefCommand_HelpDetails_Syntax, _CommandSyntax);\n            }\n            else if (string.Equals(commandInput.Arguments[0].Text, \"get\", StringComparison.OrdinalIgnoreCase))\n            {\n                helpText.AppendFormat(Resources.Strings.PrefCommand_HelpDetails_GetSyntax, _GetCommandSyntax);\n            }\n            else\n            {\n                helpText.AppendFormat(Resources.Strings.PrefCommand_HelpDetails_SetSyntax, _SetCommandSyntax);\n            }\n\n            helpText.AppendLine();\n            helpText.AppendLine(Resources.Strings.PrefCommand_HelpDetails_DefaultPreferences);\n            foreach (var pref in _preferences.DefaultPreferences)\n            {\n                var val = pref.Value;\n                if (pref.Key.Contains(\"colors\", StringComparison.OrdinalIgnoreCase))\n                {\n                    val = GetColor(val);\n                }\n                helpText.AppendLine($\"{pref.Key,-50}{val}\");\n            }\n            helpText.AppendLine();\n            helpText.AppendLine(Resources.Strings.PrefCommand_HelpDetails_CurrentPreferences);\n            foreach (var pref in _preferences.CurrentPreferences)\n            {\n                var val = pref.Value;\n                if (pref.Key.Contains(\"colors\", StringComparison.OrdinalIgnoreCase))\n                {\n                    val = GetColor(val);\n                }\n                helpText.AppendLine($\"{pref.Key,-50}{val}\");\n            }\n\n            return helpText.ToString();\n        }\n\n        private static string GetColor(string value)\n        {\n            if (value.Contains(\"Bold\", StringComparison.OrdinalIgnoreCase))\n            {\n                value = value.Bold();\n            }\n\n            if (value.Contains(\"Yellow\", StringComparison.OrdinalIgnoreCase))\n            {\n                value = value.Yellow();\n            }\n\n            if (value.Contains(\"Cyan\", StringComparison.OrdinalIgnoreCase))\n            {\n                value = value.Cyan();\n            }\n\n            if (value.Contains(\"Magenta\", StringComparison.OrdinalIgnoreCase))\n            {\n                value = value.Magenta();\n            }\n\n            if (value.Contains(\"Green\", StringComparison.OrdinalIgnoreCase))\n            {\n                value = value.Green();\n            }\n\n            if (value.Contains(\"White\", StringComparison.OrdinalIgnoreCase))\n            {\n                value = value.White();\n            }\n\n            if (value.Contains(\"Black\", StringComparison.OrdinalIgnoreCase))\n            {\n                value = value.Black();\n            }\n\n            return value;\n        }\n\n        protected override Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            commandInput = commandInput ?? throw new ArgumentNullException(nameof(commandInput));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            if (string.Equals(commandInput.Arguments[0].Text, \"get\", StringComparison.OrdinalIgnoreCase))\n            {\n                GetSetting(shellState, programState, commandInput);\n            }\n            else\n            {\n                SetSetting(shellState, programState, commandInput);\n            }\n\n            return Task.CompletedTask;\n        }\n\n        private void SetSetting(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput)\n        {\n            string prefName = commandInput.Arguments[1].Text;\n            string prefValue = commandInput.Arguments.Count > 2 ? commandInput.Arguments[2]?.Text : null;\n\n            _telemetry.TrackEvent(new PreferenceEvent(\"Set\", prefName));\n\n            if (!_preferences.SetValue(prefName, prefValue))\n            {\n                shellState.ConsoleManager.Error.WriteLine(Resources.Strings.PrefCommand_Error_Saving.SetColor(programState.ErrorColor));\n            }\n            else\n            {\n                // If we think they're configurating HttpRepl to use Visual Studio Code as their editor, we should\n                // warn them that for best integration, they should also pass the `-w` or `--wait` arguments to\n                // Visual Studio Code.\n                if (string.Equals(prefName, WellKnownPreference.DefaultEditorCommand, StringComparison.Ordinal))\n                {\n                    if (IsVSCode(prefValue))\n                    {\n                        shellState.ConsoleManager.WriteLine(string.Format(Resources.Strings.PrefCommand_Set_VSCode, WellKnownPreference.DefaultEditorArguments).SetColor(programState.WarningColor));\n                    }\n                }\n            }\n        }\n\n        private void GetSetting(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput)\n        {\n            string preferenceName = commandInput.Arguments.Count > 1 ? commandInput.Arguments[1]?.Text : null;\n\n            _telemetry.TrackEvent(new PreferenceEvent(\"Get\", preferenceName));\n\n            //If there's a particular setting to get the value of\n            if (!string.IsNullOrEmpty(preferenceName))\n            {\n                if (_preferences.TryGetValue(preferenceName, out string value))\n                {\n                    shellState.ConsoleManager.WriteLine(string.Format(Resources.Strings.PrefCommand_Get_ConfiguredValue, value));\n                }\n                else\n                {\n                    shellState.ConsoleManager.Error.WriteLine(string.Format(Resources.Strings.PrefCommand_Error_NoConfiguredValue, commandInput.Arguments[1].Text).SetColor(programState.ErrorColor));\n                }\n            }\n            else\n            {\n                foreach (KeyValuePair<string, string> entry in _preferences.CurrentPreferences.OrderBy(x => x.Key))\n                {\n                    shellState.ConsoleManager.WriteLine($\"{entry.Key}={entry.Value}\");\n                }\n            }\n\n        }\n\n        public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create(\"pref\")\n            .MinimumArgCount(1)\n            .MaximumArgCount(3)\n            .Finish();\n\n\n        protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            if (parseResult.SelectedSection == 1)\n            {\n                return _allowedSubcommands.Where(x => x.StartsWith(normalCompletionString, StringComparison.OrdinalIgnoreCase));\n            }\n\n            if (parseResult.SelectedSection == 2)\n            {\n                string prefix = parseResult.Sections.Count > 2 ? normalCompletionString : string.Empty;\n                List<string> matchingProperties = new List<string>();\n\n                foreach (string val in WellKnownPreference.Catalog.Names)\n                {\n                    if (val.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))\n                    {\n                        matchingProperties.Add(val);\n                    }\n                }\n\n                return matchingProperties;\n            }\n\n            if (parseResult.SelectedSection == 3\n                && parseResult.Sections[2].StartsWith(\"colors.\", StringComparison.OrdinalIgnoreCase))\n            {\n                string prefix = parseResult.Sections.Count > 3 ? normalCompletionString : string.Empty;\n                List<string> matchingProperties = new List<string>();\n\n                foreach (string val in Enum.GetNames(typeof(AllowedColors)))\n                {\n                    if (val.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))\n                    {\n                        matchingProperties.Add(val);\n                    }\n                }\n\n                return matchingProperties;\n            }\n\n            return null;\n        }\n\n        private static bool IsVSCode(string path)\n        {\n            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n            {\n                return path.Contains(\"Code.exe\", StringComparison.OrdinalIgnoreCase) ||\n                       path.Contains(\"Code - Insiders.exe\", StringComparison.OrdinalIgnoreCase);\n            }\n            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))\n            {\n                return path.Contains(\"Visual Studio Code.app\", StringComparison.Ordinal) ||\n                       path.Contains(\"Visual Studio Code - Insiders.app\", StringComparison.Ordinal);\n            }\n            else //  Linux\n            {\n                return string.Equals(path, \"/usr/bin/code\", StringComparison.Ordinal) ||\n                       string.Equals(path, \"/usr/bin/code-insiders\", StringComparison.Ordinal);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/PutCommand.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class PutCommand : BaseHttpCommand\n    {\n        public PutCommand(IFileSystem fileSystem, IPreferences preferences, ITelemetry telemetry) : base(fileSystem, preferences, telemetry) { }\n\n        protected override string Verb => \"put\";\n\n        protected override bool RequiresBody => true;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/RunCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Microsoft.Repl.Scripting;\nusing Microsoft.Repl.Suggestions;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class RunCommand : ICommand<HttpState, ICoreParseResult>\n    {\n        public string Name => \"run\";\n\n        private readonly IFileSystem _fileSystem;\n        public RunCommand(IFileSystem fileSystem)\n        {\n            _fileSystem = fileSystem;\n        }\n\n        public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            return parseResult.ContainsAtLeast(minimumLength: 2, Name) && parseResult.Sections.Count < 4\n                ? (bool?)true\n                : null;\n        }\n\n        public async Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            if (!_fileSystem.FileExists(parseResult.Sections[1]))\n            {\n                shellState.ConsoleManager.Error.WriteLine(string.Format(Strings.RunCommand_CouldNotFindScriptFile, parseResult.Sections[1]));\n                return;\n            }\n\n            bool suppressScriptLinesInHistory = true;\n            if (parseResult.Sections.Count == 3)\n            {\n                suppressScriptLinesInHistory = !string.Equals(parseResult.Sections[2], \"+history\", StringComparison.OrdinalIgnoreCase);\n            }\n\n            string[] lines = _fileSystem.ReadAllLinesFromFile(parseResult.Sections[1]);\n            IScriptExecutor scriptExecutor = new ScriptExecutor<HttpState, ICoreParseResult>(suppressScriptLinesInHistory);\n            await scriptExecutor.ExecuteScriptAsync(shellState, lines, cancellationToken).ConfigureAwait(false);\n        }\n\n        public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            if (parseResult.ContainsAtLeast(Name))\n            {\n                StringBuilder helpText = new StringBuilder();\n                helpText.Append(Strings.Usage.Bold());\n                helpText.AppendLine(Strings.RunCommand_HelpDetails);\n                return helpText.ToString();\n            }\n\n            return null;\n        }\n\n        public string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return Resources.Strings.RunCommand_HelpSummary;\n        }\n\n        public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            if (parseResult.SelectedSection == 0 &&\n                (string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))\n            {\n                return new[] { Name };\n            }\n\n            if (parseResult.SelectedSection == 1 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase))\n            {\n                return FileSystemCompletion.GetCompletions(parseResult.Sections[1].Substring(0, parseResult.CaretPositionWithinSelectedSection));\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/SetHeaderCommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.HttpRepl.Suggestions;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.HttpRepl.Telemetry.Events;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class SetHeaderCommand : ICommand<HttpState, ICoreParseResult>\n    {\n        private const string CommandName = \"set\";\n        private const string SubCommand = \"header\";\n\n        private readonly ITelemetry _telemetry;\n\n        public string Name => \"setHeader\";\n        public static string Description => Strings.SetHeaderCommand_HelpSummary;\n\n        public SetHeaderCommand(ITelemetry telemetry)\n        {\n            _telemetry = telemetry;\n        }\n\n        public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            return parseResult.ContainsAtLeast(minimumLength: 3, CommandName, SubCommand)\n                ? (bool?)true\n                : null;\n        }\n\n        public Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            bool isValueEmpty;\n            if (parseResult.Sections.Count == 3)\n            {\n                programState.Headers.Remove(parseResult.Sections[2]);\n                isValueEmpty = true;\n            }\n            else\n            {\n                programState.Headers[parseResult.Sections[2]] = parseResult.Sections.Skip(3).ToList();\n                isValueEmpty = false;\n            }\n\n            _telemetry.TrackEvent(new SetHeaderEvent(parseResult.Sections[2], isValueEmpty));\n\n            return Task.CompletedTask;\n        }\n\n        public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            if (parseResult.ContainsAtLeast(CommandName, SubCommand))\n            {\n                StringBuilder helpText = new StringBuilder();\n                helpText.Append(Strings.Usage.Bold());\n                helpText.AppendLine(\"set header {name} [value]\");\n                helpText.AppendLine();\n                helpText.AppendLine(Strings.SetHeaderCommand_HelpDetails);\n                return helpText.ToString();\n            }\n\n            return null;\n        }\n\n        public string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return Description;\n        }\n\n        public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            if (parseResult.Sections.Count == 0)\n            {\n                return new[] { CommandName };\n            }\n\n            if (parseResult.Sections.Count > 0 && parseResult.SelectedSection == 0 && CommandName.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase))\n            {\n                return new[] { CommandName };\n            }\n\n            if (string.Equals(CommandName, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase) && parseResult.SelectedSection == 1 && (parseResult.Sections.Count < 2 || SubCommand.StartsWith(parseResult.Sections[1].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))\n            {\n                return new[] { SubCommand };\n            }\n\n            if (parseResult.Sections.Count > 2\n                && string.Equals(CommandName, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase)\n                && string.Equals(SubCommand, parseResult.Sections[1], StringComparison.OrdinalIgnoreCase) && parseResult.SelectedSection == 2)\n            {\n                string prefix = parseResult.Sections[2].Substring(0, parseResult.CaretPositionWithinSelectedSection);\n                return HeaderCompletion.GetCompletions(null, prefix);\n            }\n\n            if (parseResult.Sections.Count > 3\n                && string.Equals(CommandName, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase)\n                && string.Equals(SubCommand, parseResult.Sections[1], StringComparison.OrdinalIgnoreCase) && parseResult.SelectedSection == 3)\n            {\n                string prefix = parseResult.Sections[3].Substring(0, parseResult.CaretPositionWithinSelectedSection);\n                return HeaderCompletion.GetValueCompletions(null, string.Empty, parseResult.Sections[2], prefix, programState);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/TreeNode.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class TreeNode\n    {\n        private readonly int _depth;\n        private readonly Formatter _formatter;\n        private readonly string _prefix;\n        private readonly string _entry;\n        private readonly List<TreeNode> _children = new List<TreeNode>();\n\n        public IReadOnlyList<TreeNode> Children => _children;\n\n        public TreeNode(Formatter formatter, string prefix, string entry)\n            : this(formatter, prefix, entry, 0)\n        {\n        }\n\n        private TreeNode(Formatter formatter, string prefix, string entry, int depth)\n        {\n            _formatter = formatter ?? throw new ArgumentNullException(nameof(formatter));\n            _prefix = prefix ?? throw new ArgumentNullException(nameof(prefix));\n            formatter.RegisterEntry(prefix.Length, depth);\n            _entry = entry;\n            _depth = depth;\n        }\n\n        public TreeNode AddChild(string prefix, string entry)\n        {\n            TreeNode child = new TreeNode(_formatter, prefix, entry, _depth + 1);\n            _children.Add(child);\n            return child;\n        }\n\n        public override string ToString()\n        {\n            string self = _formatter.Format(_prefix, _entry, _depth);\n\n            if (_children.Count == 0)\n            {\n                return self;\n            }\n\n            return self + Environment.NewLine + string.Join(Environment.NewLine, _children);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Commands/UICommand.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Commands\n{\n    public class UICommand : ICommand<HttpState, ICoreParseResult>\n    {\n        public string Name => \"ui\";\n        private readonly IUriLauncher _uriLauncher;\n        private readonly IPreferences _preferences;\n\n        public UICommand(IUriLauncher uriLauncher, IPreferences preferences)\n        {\n            _uriLauncher = uriLauncher ?? throw new ArgumentNullException(nameof(uriLauncher));\n            _preferences = preferences ?? throw new ArgumentNullException(nameof(preferences));\n        }\n\n        public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            return parseResult.ContainsAtLeast(Name)\n                ? (bool?)true\n                : null;\n        }\n\n        public Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            if (programState.BaseAddress == null)\n            {\n                shellState.ConsoleManager.Error.WriteLine(Strings.UICommand_NotConnectedToServerError.SetColor(programState.ErrorColor));\n                return Task.CompletedTask;\n            }\n\n            Uri uri = null;\n\n            // Try to use the parameter first, if there was one.\n            if (parseResult.Sections.Count > 1)\n            {\n                string parameter = parseResult.Sections[1];\n\n                if (Uri.IsWellFormedUriString(parameter, UriKind.Absolute))\n                {\n                    uri = new Uri(parameter, UriKind.Absolute);\n                }\n                else if (!Uri.TryCreate(programState.BaseAddress, parameter, out uri))\n                {\n                    uri = null;\n                }\n\n                // If they specified a parameter and it failed, bail out\n                if (uri is null)\n                {\n                    shellState.ConsoleManager.Error.WriteLine(string.Format(Strings.UICommand_InvalidParameter, parameter).SetColor(programState.ErrorColor));\n                    return Task.CompletedTask;\n                }\n            }\n\n            // If no parameter specified, check the preferences or use the default\n            if (uri is null)\n            {\n                string uiEndpoint = _preferences.GetValue(WellKnownPreference.SwaggerUIEndpoint, \"swagger\");\n                if (Uri.IsWellFormedUriString(uiEndpoint, UriKind.Absolute))\n                {\n                    uri = new Uri(uiEndpoint, UriKind.Absolute);\n                }\n                else\n                {\n                    uri = new Uri(programState.BaseAddress, uiEndpoint);\n                }\n            }\n\n            return _uriLauncher.LaunchUriAsync(uri);\n        }\n\n        private string _HelpText;\n        private string HelpText\n        {\n            get\n            {\n                if (_HelpText is null)\n                {\n                    string parameter = \"{swaggerUIAddress}\";\n                    string defaultAddress = \"[BaseAddress]/swagger\";\n                    StringBuilder helpText = new StringBuilder();\n                    helpText.Append(Strings.Usage.Bold());\n                    helpText.AppendLine(\"ui [{swaggerUIAddress}]\");\n                    helpText.AppendLine();\n                    helpText.AppendLine(Strings.UICommand_Description);\n                    helpText.AppendLine();\n                    helpText.AppendLine(string.Format(Strings.UICommand_HelpText_Line1, Name));\n                    helpText.AppendLine(string.Format(Strings.UICommand_HelpText_Line2, parameter));\n                    helpText.AppendLine(string.Format(Strings.UICommand_HelpText_Line3, WellKnownPreference.SwaggerUIEndpoint));\n                    helpText.AppendLine(string.Format(Strings.UICommand_HelpText_Line4, defaultAddress));\n\n                    _HelpText = helpText.ToString();\n                }\n                return _HelpText;\n            }\n        }\n\n        public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            if (parseResult.ContainsAtLeast(Name))\n            {\n                return HelpText;\n            }\n\n            return null;\n        }\n\n        public string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return Resources.Strings.UICommand_HelpSummary;\n        }\n\n        public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            if (parseResult.SelectedSection == 0 &&\n                (string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))\n            {\n                return new[] { Name };\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/DirectoryStructure.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Microsoft.HttpRepl\n{\n    public class DirectoryStructure : IDirectoryStructure\n    {\n        private readonly Dictionary<string, DirectoryStructure> _childDirectories = new Dictionary<string, DirectoryStructure>(StringComparer.OrdinalIgnoreCase);\n\n        public DirectoryStructure(IDirectoryStructure parent)\n        {\n            Parent = parent;\n        }\n\n        public IEnumerable<string> DirectoryNames => _childDirectories.Keys;\n\n        public IDirectoryStructure Parent { get; }\n\n        public DirectoryStructure DeclareDirectory(string name)\n        {\n            if (_childDirectories.TryGetValue(name, out DirectoryStructure existing))\n            {\n                return existing;\n            }\n\n            return _childDirectories[name] = new DirectoryStructure(this);\n        }\n\n        public IDirectoryStructure GetChildDirectory(string name)\n        {\n            if (_childDirectories.TryGetValue(name, out DirectoryStructure result))\n            {\n                return result;\n            }\n\n            IDirectoryStructure parameterizedTarget = _childDirectories.FirstOrDefault(x => x.Key.StartsWith('{') && x.Key.EndsWith('}')).Value;\n\n            if (parameterizedTarget is object)\n            {\n                return parameterizedTarget;\n            }\n\n            return new DirectoryStructure(this);\n        }\n\n        public IRequestInfo RequestInfo { get; set;  }\n    }\n\n    public class RequestInfo : IRequestInfo\n    {\n        private readonly HashSet<string> _methods = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\n        private readonly Dictionary<string, Dictionary<string, string>> _requestBodiesByMethodByContentType = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);\n        private readonly Dictionary<string, string> _fallbackBodyStringsByMethod = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n        private readonly Dictionary<string, string> _fallbackContentTypeStringsByMethod = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n        private readonly Dictionary<string, IReadOnlyList<string>> _contentTypesByMethod = new Dictionary<string, IReadOnlyList<string>>(StringComparer.OrdinalIgnoreCase);\n\n        public IReadOnlyList<string> Methods => _methods.ToList();\n\n        public IReadOnlyDictionary<string, IReadOnlyList<string>> ContentTypesByMethod => _contentTypesByMethod;\n\n        public string GetRequestBodyForContentType(ref string contentType, string method)\n        {\n            if (_requestBodiesByMethodByContentType.TryGetValue(method, out Dictionary<string, string> bodiesByContentType)\n                && bodiesByContentType.TryGetValue(contentType, out string body))\n            {\n                return body;\n            }\n\n            if (_fallbackBodyStringsByMethod.TryGetValue(method, out body))\n            {\n                if (_fallbackContentTypeStringsByMethod.TryGetValue(method, out string newContentType))\n                {\n                    contentType = newContentType;\n                }\n\n                return body;\n            }\n\n            return null;\n        }\n\n        public void SetRequestBody(string method, string contentType, string body)\n        {\n            if (!_requestBodiesByMethodByContentType.TryGetValue(method, out Dictionary<string, string> bodiesByContentType))\n            {\n                _requestBodiesByMethodByContentType[method] = bodiesByContentType = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n            }\n\n            if (!_contentTypesByMethod.TryGetValue(method, out IReadOnlyList<string> contentTypesRaw))\n            {\n                _contentTypesByMethod[method] = contentTypesRaw = new List<string>();\n            }\n\n            List<string> contentTypes = (List<string>)contentTypesRaw;\n            contentTypes.Add(contentType);\n\n            bodiesByContentType[contentType] = body;\n        }\n\n        public void AddMethod(string method)\n        {\n            _methods.Add(method);\n        }\n\n        public void SetFallbackRequestBody(string method, string contentType, string fallbackBodyString)\n        {\n            _fallbackBodyStringsByMethod[method] = fallbackBodyString;\n            _fallbackContentTypeStringsByMethod[method] = contentType;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/DirectoryStructureExtensions.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Microsoft.HttpRepl\n{\n    public static class DirectoryStructureExtensions\n    {\n        public static IEnumerable<string> GetDirectoryListingAtPath(this IDirectoryStructure structure, string path)\n        {\n            structure = structure ?? throw new ArgumentNullException(nameof(structure));\n            return structure.TraverseTo(path).DirectoryNames;\n        }\n\n        public static IDirectoryStructure TraverseTo(this IDirectoryStructure structure, string path)\n        {\n            structure = structure ?? throw new ArgumentNullException(nameof(structure));\n            path = path ?? throw new ArgumentNullException(nameof(path));\n\n            string[] parts = path.Replace('\\\\', '/').Split('/');\n            return structure.TraverseTo(parts);\n        }\n\n        public static IDirectoryStructure TraverseTo(this IDirectoryStructure structure, IEnumerable<string> pathParts)\n        {\n            structure = structure ?? throw new ArgumentNullException(nameof(structure));\n\n            IDirectoryStructure s = structure;\n\n            if (pathParts is null)\n            {\n                return s;\n            }\n\n            IReadOnlyList<string> parts = pathParts.ToList();\n            if (parts.Count == 0)\n            {\n                return s;\n            }\n\n            if (parts[0].Length == 0 && parts.Count > 1)\n            {\n                while (s.Parent != null)\n                {\n                    s = s.Parent;\n                }\n            }\n\n            foreach (string part in parts)\n            {\n                if (part == \".\")\n                {\n                    continue;\n                }\n\n                if (part == \"..\")\n                {\n                    s = s?.Parent ?? s;\n                }\n                else if (!string.IsNullOrEmpty(part) && s is object)\n                {\n                    s = s.GetChildDirectory(part);\n                }\n            }\n\n            return s;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Extensions/RequestInfoExtensions.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Microsoft.HttpRepl\n{\n    public static class RequestInfoExtensions\n    {\n        public static string GetDirectoryMethodListing(this IRequestInfo requestInfo)\n        {\n            if (requestInfo is null || requestInfo.Methods is null || requestInfo.Methods.Count == 0)\n            {\n                return \"[]\";\n            }\n\n            IEnumerable<string> upperCaseMethods = requestInfo.Methods.Select(s => s?.ToUpperInvariant());\n\n            return \"[\" + string.Join(\"|\", upperCaseMethods) + \"]\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Extensions/UrlStringExtensions.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.txt file in the project root for more information.\n\nusing System;\n\nnamespace Microsoft.HttpRepl\n{\n    public static class UrlStringExtensions\n    {\n        public static string EnsureTrailingSlash(this string url)\n        {\n            url = url ?? throw new ArgumentNullException(nameof(url));\n\n            if (!url.EndsWith(\"/\", StringComparison.Ordinal))\n            {\n                url += \"/\";\n            }\n\n            return url;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/FileSystem/IFileSystem.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl.FileSystem\n{\n    public interface IFileSystem\n    {\n        void DeleteFile(string path);\n        bool FileExists(string path);\n        string GetTempFileName(string fileExtension);\n        byte[] ReadAllBytesFromFile(string path);\n        string[] ReadAllLinesFromFile(string path);\n        void WriteAllTextToFile(string path, string contents);\n        void WriteAllLinesToFile(string path, IEnumerable<string> contents);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/FileSystem/RealFileSystem.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing Microsoft.HttpRepl.Resources;\n\nnamespace Microsoft.HttpRepl.FileSystem\n{\n    internal class RealFileSystem : IFileSystem\n    {\n        public bool FileExists(string path)\n        {\n            return File.Exists(path);\n        }\n\n        public void WriteAllTextToFile(string path, string contents)\n        {\n            VerifyDirectoryExists(path);\n            File.WriteAllText(path, contents);\n        }\n\n        public byte[] ReadAllBytesFromFile(string path)\n        {\n            return File.ReadAllBytes(path);\n        }\n\n        public string[] ReadAllLinesFromFile(string path)\n        {\n            return File.ReadAllLines(path);\n        }\n\n        public void WriteAllLinesToFile(string path, IEnumerable<string> contents)\n        {\n            VerifyDirectoryExists(path);\n            File.WriteAllLines(path, contents);\n        }\n\n        public void DeleteFile(string path)\n        {\n            File.Delete(path);\n        }\n\n        public string GetTempFileName(string fileExtension)\n        {\n            fileExtension = fileExtension ?? throw new ArgumentNullException(nameof(fileExtension));\n\n            if (!fileExtension.StartsWith(\".\", StringComparison.Ordinal) || fileExtension.Length < 2)\n            {\n                throw new ArgumentException(string.Format(Strings.RealFileSystem_Error_InvalidExtension, nameof(fileExtension)), nameof(fileExtension));\n            }\n\n            string tempFileName = Path.Combine(Path.GetTempPath(), GetRandomFileName(fileExtension));\n\n            return tempFileName;\n        }\n\n        private static string GetRandomFileName(string fileExtension)\n        {\n            // Start it with HttpRepl so we can easily find it if necessary for debugging, etc\n            // Use a GUID to make it unique enough\n            return \"HttpRepl.\" + Guid.NewGuid().ToString() + fileExtension;\n        }\n\n        private static void VerifyDirectoryExists(string path)\n        {\n            Directory.CreateDirectory(Path.GetDirectoryName(path));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Formatting/JsonVisitor.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.txt file in the project root for more information.\n\nusing System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Text;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl.ConsoleHandling;\nusing Newtonsoft.Json;\n\nnamespace Microsoft.HttpRepl.Formatting\n{\n    public static class JsonVisitor\n    {\n        [SuppressMessage(\"Design\", \"CA1308:Normalize strings to uppercase\", Justification = \"JSON is case-sensitive.\")]\n        public static string FormatAndColorize(IJsonConfig config, string jsonData)\n        {\n            config = config ?? throw new ArgumentNullException(nameof(config));\n\n            if (jsonData == null)\n            {\n                return string.Empty;\n            }\n\n            StringBuilder result = new StringBuilder();\n            using (JsonTextReader reader = new JsonTextReader(new StringReader(jsonData)))\n            {\n                bool isValuePosition = false;\n                bool isTerminalValue = false;\n                bool isFirstToken = true;\n\n                while (reader.Read())\n                {\n                    if (!isValuePosition)\n                    {\n                        //If we're about to write an end object/array, we shouldn't have a comma\n                        if (reader.TokenType != JsonToken.EndArray && reader.TokenType != JsonToken.EndObject\n                            && isTerminalValue)\n                        {\n                            result.Append(\",\".SetColor(config.CommaColor));\n                        }\n\n                        if (!isFirstToken)\n                        {\n                            result.AppendLine();\n                        }\n                    }\n\n                    isFirstToken = false;\n\n                    if (!isValuePosition)\n                    {\n                        result.Append(\"\".PadLeft(reader.Depth * config.IndentSize));\n                    }\n\n                    isTerminalValue = false;\n                    isValuePosition = false;\n                    JsonToken type = reader.TokenType;\n\n                    switch (type)\n                    {\n                        case JsonToken.StartObject:\n                            result.Append(\"{\".SetColor(config.ObjectBraceColor));\n                            break;\n                        case JsonToken.EndObject:\n                            result.Append(\"}\".SetColor(config.ObjectBraceColor));\n                            isTerminalValue = true;\n                            break;\n                        case JsonToken.StartArray:\n                            result.Append(\"[\".SetColor(config.ArrayBraceColor));\n                            break;\n                        case JsonToken.EndArray:\n                            result.Append(\"]\".SetColor(config.ArrayBraceColor));\n                            isTerminalValue = true;\n                            break;\n                        case JsonToken.PropertyName:\n                            result.Append((reader.QuoteChar.ToString() + reader.Value + reader.QuoteChar).SetColor(config.NameColor) + \": \".SetColor(config.NameSeparatorColor));\n                            isValuePosition = true;\n                            break;\n                        case JsonToken.Boolean:\n                            result.Append(reader.Value.ToString().ToLowerInvariant().SetColor(config.BoolColor));\n                            isTerminalValue = true;\n                            break;\n                        case JsonToken.Integer:\n                        case JsonToken.Float:\n                            result.Append(reader.Value.ToString().ToLowerInvariant().SetColor(config.NumericColor));\n                            isTerminalValue = true;\n                            break;\n                        case JsonToken.Null:\n                            result.Append(\"null\".SetColor(config.NullColor));\n                            isTerminalValue = true;\n                            break;\n                        case JsonToken.Comment:\n                            result.Append((\"//\" + reader.Value).SetColor(config.NumericColor));\n                            break;\n                        case JsonToken.String:\n                            result.Append((reader.QuoteChar.ToString() + reader.Value + reader.QuoteChar.ToString()).SetColor(config.StringColor));\n                            isTerminalValue = true;\n                            break;\n                        case JsonToken.Raw:\n                        case JsonToken.Date:\n                        case JsonToken.Bytes:\n                        case JsonToken.Undefined:\n                        case JsonToken.None:\n                            result.Append(reader.Value.ToString().SetColor(config.DefaultColor));\n                            isTerminalValue = true;\n                            break;\n                        case JsonToken.EndConstructor:\n                        case JsonToken.StartConstructor:\n                        default:\n                            result.Append(reader.Value.ToString().SetColor(config.DefaultColor));\n                            break;\n                    }\n                }\n            }\n            return result.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/HttpState.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing Microsoft.HttpRepl.OpenApi;\nusing Microsoft.HttpRepl.Preferences;\nusing System.Net;\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl\n{\n    public class HttpState\n    {\n        private readonly IPreferences _preferences;\n\n        public HttpClient Client { get; }\n\n        public AllowedColors ErrorColor => _preferences.GetColorValue(WellKnownPreference.ErrorColor, AllowedColors.BoldRed);\n\n        public AllowedColors WarningColor => _preferences.GetColorValue(WellKnownPreference.WarningColor, AllowedColors.BoldYellow);\n\n        public Stack<string> PathSections { get; }\n\n        public ApiDefinition ApiDefinition { get; set; }\n\n        public Uri BaseAddress { get; set; }\n\n        public IDirectoryStructure Structure => ApiDefinition?.DirectoryStructure;\n\n        public bool EchoRequest { get; set; }\n\n        public Dictionary<string, IEnumerable<string>> Headers { get; }\n\n        public Dictionary<string, IEnumerable<string>> QueryParam { get; set; } = new();\n\n        public Uri SwaggerEndpoint { get; set; }\n\n        public HttpState(IPreferences preferences, HttpClient httpClient)\n        {\n            preferences = preferences ?? throw new ArgumentNullException(nameof(preferences));\n\n            _preferences = preferences;\n            Client = httpClient;\n            PathSections = new Stack<string>();\n            Headers = new Dictionary<string, IEnumerable<string>>(StringComparer.OrdinalIgnoreCase);\n            AddDefaultHeaders();\n        }\n\n        public string GetPrompt()\n        {\n            return $\"{GetEffectivePathForPrompt()?.ToString() ?? \"(Disconnected)\"}> \";\n        }\n\n        public IEnumerable<string> GetApplicableContentTypes(string method, string path)\n        {\n            if (BaseAddress is null && !Uri.IsWellFormedUriString(path, UriKind.Absolute))\n            {\n                return null;\n            }\n\n            Uri effectivePath = GetEffectivePathWithoutQueryParam(path);\n            string rootRelativePath = effectivePath.LocalPath.Substring(BaseAddress.LocalPath.Length).TrimStart('/');\n            IDirectoryStructure structure = Structure?.TraverseTo(rootRelativePath);\n            IReadOnlyDictionary<string, IReadOnlyList<string>> contentTypesByMethod = structure?.RequestInfo?.ContentTypesByMethod;\n\n            if (contentTypesByMethod != null)\n            {\n                if (method is null)\n                {\n                    return contentTypesByMethod.Values.SelectMany(x => x).Distinct(StringComparer.OrdinalIgnoreCase);\n                }\n\n                if (contentTypesByMethod.TryGetValue(method, out IReadOnlyList<string> contentTypes))\n                {\n                    return contentTypes;\n                }\n            }\n\n            return null;\n        }\n\n        internal Uri GetEffectivePathWithoutQueryParam(string commandSpecifiedPath) =>\n            GetEffectivePath(BaseAddress, string.Join('/', PathSections.Reverse()), commandSpecifiedPath, queryParam: null);\n       \n    \n        public Uri GetEffectivePath(string commandSpecifiedPath) =>\n            GetEffectivePath(BaseAddress, string.Join('/', PathSections.Reverse()), commandSpecifiedPath, QueryParam);\n\n        internal static Uri GetEffectivePath(Uri baseAddress, string pathSections, string commandSpecifiedPath, Dictionary<string, IEnumerable<string>> queryParam)\n        {\n            // If an absolute uri string was already specified, just return that.\n            if (Uri.IsWellFormedUriString(commandSpecifiedPath, UriKind.Absolute))\n            {\n                return new Uri(commandSpecifiedPath, UriKind.Absolute);\n            }\n            // If it wasn't, and there also isn't a base address, throw an exception\n            else if (baseAddress == null)\n            {\n                throw new ArgumentNullException(nameof(baseAddress), string.Format(Resources.Strings.HttpState_Error_NoAbsoluteUriNoBaseAddress, nameof(commandSpecifiedPath), nameof(baseAddress)));\n            }\n\n            pathSections = pathSections ?? throw new ArgumentNullException(nameof(pathSections));\n\n            UriBuilder builder = GetUriBuilderFromBaseAddressAndPath(baseAddress, pathSections, out string baseAndPathQuery);\n\n            UpdateUriBuilderForSpecifiedPath(builder, commandSpecifiedPath, out string commandQuery);\n            AppendQueryToBuilder(builder, baseAndPathQuery);\n            AppendQueryToBuilder(builder, commandQuery);\n\n            if (queryParam is not null)\n            {\n                foreach (KeyValuePair<string, IEnumerable<string>> tuple in queryParam)\n                {\n                    foreach (var singleValue in tuple.Value)\n                    {\n                        AppendQueryToBuilder(builder, $\"{WebUtility.UrlEncode(tuple.Key)}={WebUtility.UrlEncode(singleValue)}\");\n                    }\n                }\n            }\n\n            return builder.Uri;\n        }\n\n        public Uri GetEffectivePathForPrompt()\n        {\n            if (BaseAddress == null)\n            {\n                return null;\n            }\n\n            return GetEffectivePath(BaseAddress, string.Join('/', PathSections.Reverse()), \"\", queryParam: null);\n        }\n\n        public string GetRelativePathString()\n        {\n            string pathString = \"/\";\n\n            if (PathSections != null && PathSections.Count > 0)\n            {\n                pathString += string.Join(\"/\", PathSections.Reverse());\n            }\n\n            return pathString;\n        }\n\n        private static UriBuilder GetUriBuilderFromBaseAddressAndPath(Uri baseAddress, string pathSections, out string query)\n        {\n            // Get a builder for the base address\n            UriBuilder builder = new UriBuilder(baseAddress);\n\n            // Get everything beyond the BaseAddress for the current location\n            string path = pathSections;\n\n            // Split that off into the path and the query string parameters (if any)\n            string[] parts = path.Split('?');\n            query = null;\n\n            // If there are some query string parameters, split the path off so it doesn't\n            // contain them and leave the query string parameters in query\n            if (parts.Length > 1)\n            {\n                path = parts[0];\n                query = string.Join('?', parts.Skip(1));\n            }\n\n            if (path.StartsWith('/'))\n            {\n                // Set the builder path to the current path\n                builder.Path = path;\n            }\n            else\n            {\n                // Add the current path to the builder path\n                builder.Path += path;\n            }\n\n            return builder;\n        }\n\n        private static void UpdateUriBuilderForSpecifiedPath(UriBuilder builder, string commandSpecifiedPath, out string query)\n        {\n            query = null;\n            // If the parameter has a non-empty value\n            if (!string.IsNullOrEmpty(commandSpecifiedPath))\n            {\n                // If the parameter doesn't start with a slash\n                if (commandSpecifiedPath[0] != '/')\n                {\n                    // If the current builder path doesn't end with a slash, then add one to the parameter\n                    string argPath = commandSpecifiedPath;\n                    if (builder.Path.Length > 0 && builder.Path[builder.Path.Length - 1] != '/')\n                    {\n                        argPath = \"/\" + argPath;\n                    }\n\n                    // Split the parameter between the path and the query string\n                    int queryIndex = argPath.IndexOf('?', StringComparison.Ordinal);\n                    string path = argPath;\n\n                    if (queryIndex > -1)\n                    {\n                        query = argPath.Substring(queryIndex + 1);\n                        path = argPath.Substring(0, queryIndex);\n                    }\n\n                    // Add just the path part of the parameter to the current builder path\n                    builder.Path += path;\n                }\n                // if the parameter does start with a slash\n                else\n                {\n                    // Split the parameter between the path and the query string\n                    int queryIndex = commandSpecifiedPath.IndexOf('?', StringComparison.Ordinal);\n                    string path = commandSpecifiedPath;\n\n                    if (queryIndex > -1)\n                    {\n                        query = commandSpecifiedPath.Substring(queryIndex + 1);\n                        path = commandSpecifiedPath.Substring(0, queryIndex);\n                    }\n\n                    // Set the builder path to just the path part of the parameter\n                    builder.Path = path;\n                }\n            }\n        }\n\n        private static void AppendQueryToBuilder(UriBuilder builder, string query)\n        {\n            if (query != null)\n            {\n                if (!string.IsNullOrEmpty(builder.Query))\n                {\n                    query = \"&\" + query;\n                }\n\n                builder.Query += query;\n            }\n        }\n\n        private void AddDefaultHeaders()\n        {\n            Headers[\"User-Agent\"] = new[] { _preferences.GetValue(WellKnownPreference.HttpClientUserAgent, \"HTTP-REPL\") };\n        }\n\n        public void ResetState(bool persistHeaders = false, bool persistPath = false)\n        {\n            BaseAddress = null;\n            SwaggerEndpoint = null;\n\n            if (!persistHeaders)\n            {\n                Headers.Clear();\n                AddDefaultHeaders();\n            }\n\n            if (!persistPath)\n            {\n                PathSections.Clear();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/IDirectoryStructure.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl\n{\n    public interface IDirectoryStructure\n    {\n        IEnumerable<string> DirectoryNames { get; }\n\n        IDirectoryStructure Parent { get; }\n\n        IDirectoryStructure GetChildDirectory(string name);\n\n        IRequestInfo RequestInfo { get; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/IRequestInfo.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl\n{\n    public interface IRequestInfo\n    {\n        IReadOnlyDictionary<string, IReadOnlyList<string>> ContentTypesByMethod { get; }\n\n        IReadOnlyList<string> Methods { get; }\n\n        string GetRequestBodyForContentType(ref string contentType, string method);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/IUriLauncher.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.txt file in the project root for more information.\n\nusing System;\nusing System.Threading.Tasks;\n\nnamespace Microsoft.HttpRepl\n{\n    public interface IUriLauncher\n    {\n        Task LaunchUriAsync(Uri uri);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Microsoft.HttpRepl.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0</TargetFramework>\n    <RollForward>Major</RollForward>\n    <AssemblyName>httprepl</AssemblyName>\n    <Description>The HTTP Read-Eval-Print Loop (REPL) is a lightweight, cross-platform command-line tool that's supported everywhere .NET Core is supported and is used for making HTTP requests to test ASP.NET Core web APIs and view their results.</Description>\n    <PackageId>Microsoft.dotnet-httprepl</PackageId>\n    <PackageTags>dotnet;http;httprepl</PackageTags>\n    <PackageProjectUrl>https://aka.ms/http-repl-doc</PackageProjectUrl>\n\n    <IsPackable>true</IsPackable>\n    <PackAsTool>true</PackAsTool>\n    <PackAsToolShimRuntimeIdentifiers>win-x64;win-x86</PackAsToolShimRuntimeIdentifiers>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.AspNet.WebApi.Client\" />\n    <PackageReference Include=\"Microsoft.OpenApi.Readers\" />\n    <PackageReference Include=\"System.Text.Encoding.CodePages\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"$(RepoSource)\\Microsoft.HttpRepl.Telemetry\\Microsoft.HttpRepl.Telemetry.csproj\" />\n    <ProjectReference Include=\"$(RepoSource)\\Microsoft.Repl\\Microsoft.Repl.csproj\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Compile Update=\"Resources\\Strings.Designer.cs\">\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Strings.resx</DependentUpon>\n    </Compile>\n  </ItemGroup>\n\n  <ItemGroup>\n    <EmbeddedResource Update=\"Resources\\Strings.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Strings.Designer.cs</LastGenOutput>\n    </EmbeddedResource>\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Include=\"..\\..\\NOTICE.txt\" Pack=\"true\" PackagePath=\"\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/OpenApi/ApiDefinition.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace Microsoft.HttpRepl.OpenApi\n{\n    public class ApiDefinition\n    {\n        public IList<Server> BaseAddresses { get; } = new List<Server>();\n        public IDirectoryStructure DirectoryStructure { get; set; }\n\n        [SuppressMessage(\"Design\", \"CA1724:Type names should not match namespaces\", Justification = \"This is a valid name for this type.\")]\n        public class Server\n        {\n            public Uri Url { get; set; }\n            public string Description { get; set; }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/OpenApi/ApiDefinitionParseResult.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.txt file in the project root for more information.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl.OpenApi\n{\n    public class ApiDefinitionParseResult\n    {\n        public static ApiDefinitionParseResult Failed { get; } = new ApiDefinitionParseResult(false, null, null);\n\n        public bool Success { get; private set; }\n        public IReadOnlyCollection<string> ValidationMessages { get; private set; }\n        public ApiDefinition? ApiDefinition { get; private set; }\n\n        public ApiDefinitionParseResult(bool success, ApiDefinition? apiDefinition, IEnumerable<string>? validationMessages)\n        {\n            Success = success;\n            ApiDefinition = apiDefinition;\n            ValidationMessages = validationMessages is null ? Array.Empty<string>() : new List<string>(validationMessages);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/OpenApi/ApiDefinitionReader.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.txt file in the project root for more information.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl.OpenApi\n{\n    internal class ApiDefinitionReader\n    {\n        private readonly List<IApiDefinitionReader> _readers = new List<IApiDefinitionReader>\n        {\n            new OpenApiDotNetApiDefinitionReader(),\n        };\n\n        internal void RegisterReader(IApiDefinitionReader reader)\n        {\n            _readers.Add(reader);\n        }\n\n        public ApiDefinitionParseResult CanHandle(string document)\n        {\n            if (document is null)\n            {\n                return ApiDefinitionParseResult.Failed;\n            }\n\n            foreach (IApiDefinitionReader reader in _readers)\n            {\n                ApiDefinitionParseResult result = reader.CanHandle(document);\n                if (result.Success)\n                {\n                    return result;\n                }\n            }\n            return ApiDefinitionParseResult.Failed;\n        }\n\n        public ApiDefinitionParseResult Read(string document, Uri? swaggerUri)\n        {\n            foreach (IApiDefinitionReader reader in _readers)\n            {\n                ApiDefinitionParseResult parseResult = reader.CanHandle(document);\n                if (parseResult.Success)\n                {\n                    ApiDefinitionParseResult result = reader.ReadDefinition(document, swaggerUri);\n\n                    return result;\n                }\n            }\n\n            return ApiDefinitionParseResult.Failed;\n        }\n\n        public static void FillDirectoryInfo(DirectoryStructure parent, EndpointMetadata entry)\n        {\n            entry = entry ?? throw new ArgumentNullException(nameof(entry));\n\n            parent = parent ?? throw new ArgumentNullException(nameof(parent));\n\n            string[] parts = entry.Path.Split('/');\n\n            foreach (string part in parts)\n            {\n                if (!string.IsNullOrEmpty(part) && parent is object)\n                {\n                    parent = parent.DeclareDirectory(part);\n                }\n            }\n\n            RequestInfo dirRequestInfo = new RequestInfo();\n\n            foreach (RequestMetadata requestMetadata in entry.AvailableRequests)\n            {\n                string method = requestMetadata.Operation.ToString();\n\n                foreach (RequestContentMetadata content in requestMetadata.Content)\n                {\n                    if (string.IsNullOrWhiteSpace(content.ContentType))\n                    {\n                        dirRequestInfo.SetFallbackRequestBody(method, content.ContentType, SchemaDataGenerator.GetBodyString(content.BodySchema));\n                    }\n\n                    dirRequestInfo.SetRequestBody(method, content.ContentType, SchemaDataGenerator.GetBodyString(content.BodySchema));\n                }\n\n                dirRequestInfo.AddMethod(requestMetadata.Operation.ToString());\n            }\n\n            if (dirRequestInfo.Methods.Count > 0 && parent is object)\n            {\n                parent.RequestInfo = dirRequestInfo;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/OpenApi/EndpointMetadata.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing Microsoft.OpenApi.Models;\n\nnamespace Microsoft.HttpRepl.OpenApi\n{\n    internal class EndpointMetadata\n    {\n        public EndpointMetadata(string path)\n        {\n            Path = path;\n        }\n\n        public string Path { get; }\n\n        public ICollection<RequestMetadata> AvailableRequests { get; } = new List<RequestMetadata>();\n    }\n\n    internal class RequestMetadata\n    {\n        public RequestMetadata(OperationType operation)\n        {\n            Operation = operation;\n        }\n\n        public OperationType Operation { get; }\n\n        public ICollection<RequestContentMetadata> Content { get; } = new List<RequestContentMetadata>();\n\n        public ICollection<OpenApiParameter> Parameters { get; } = new List<OpenApiParameter>();\n    }\n\n    internal class RequestContentMetadata\n    {\n        public RequestContentMetadata(string contentType, bool isRequired, OpenApiSchema bodySchema)\n        {\n            ContentType = contentType;\n            IsRequired = isRequired;\n            BodySchema = bodySchema;\n        }\n\n        public string ContentType { get; }\n\n        public bool IsRequired { get; }\n\n        public OpenApiSchema BodySchema { get; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/OpenApi/IApiDefinitionReader.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.txt file in the project root for more information.\n\n#nullable enable\n\nusing System;\n\nnamespace Microsoft.HttpRepl.OpenApi\n{\n    public interface IApiDefinitionReader\n    {\n        ApiDefinitionParseResult CanHandle(string document);\n\n        ApiDefinitionParseResult ReadDefinition(string document, Uri? sourceUri);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/OpenApi/IOpenApiSearchPathsProvider.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.txt file in the project root for more information.\n\n#nullable enable\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl.OpenApi\n{\n    internal interface IOpenApiSearchPathsProvider\n    {\n        IEnumerable<string> GetOpenApiSearchPaths();\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/OpenApi/OpenApiDotNetApiDefinitionReader.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.txt file in the project root for more information.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.OpenApi.Models;\nusing Microsoft.OpenApi.Readers;\n\nnamespace Microsoft.HttpRepl.OpenApi\n{\n    internal class OpenApiDotNetApiDefinitionReader : IApiDefinitionReader\n    {\n        public ApiDefinitionParseResult CanHandle(string document)\n        {\n            OpenApiStringReader reader = new();\n\n            try\n            {\n                OpenApiDocument openApiDocument = reader.Read(document, out OpenApiDiagnostic diagnostic);\n\n                IEnumerable<string> messages = diagnostic.Errors.Select(e => e.ToString());\n\n                return new ApiDefinitionParseResult(true, null, messages);\n            }\n            catch\n            {\n                return ApiDefinitionParseResult.Failed;\n            }\n        }\n\n        public ApiDefinitionParseResult ReadDefinition(string document, Uri? sourceUri)\n        {\n            OpenApiStringReader reader = new();\n\n            OpenApiDocument openApiDocument = reader.Read(document, out OpenApiDiagnostic diagnostic);\n\n            ApiDefinition apiDefinition = new ApiDefinition();\n\n            ReadServers(apiDefinition, sourceUri, openApiDocument);\n\n            IList<EndpointMetadata> metadata = ReadPaths(openApiDocument);\n\n            apiDefinition.DirectoryStructure = BuildDirectoryStructure(metadata);\n\n            return new ApiDefinitionParseResult(true, apiDefinition, diagnostic.Errors.Select(e => e.ToString()));\n        }\n\n        private static void ReadServers(ApiDefinition apiDefinition, Uri? sourceUri, OpenApiDocument openApiDocument)\n        {\n            foreach (OpenApiServer server in openApiDocument.Servers)\n            {\n                string? url = server.Url?.EnsureTrailingSlash();\n                string description = server.Description;\n\n                if (url is null)\n                {\n                    continue;\n                }\n\n                if (Uri.IsWellFormedUriString(url, UriKind.Absolute) && Uri.TryCreate(url, UriKind.Absolute, out Uri? absoluteServerUri))\n                {\n                    apiDefinition.BaseAddresses.Add(new ApiDefinition.Server() { Url = absoluteServerUri, Description = description });\n                }\n                else if (Uri.TryCreate(sourceUri, url, out Uri? relativeServerUri))\n                {\n                    apiDefinition.BaseAddresses.Add(new ApiDefinition.Server() { Url = relativeServerUri, Description = description });\n                }\n            }\n        }\n\n        private static IList<EndpointMetadata> ReadPaths(OpenApiDocument openApiDocument)\n        {\n            List<EndpointMetadata> metadata = new List<EndpointMetadata>();\n\n            if (openApiDocument.Paths is not null)\n            {\n                foreach (KeyValuePair<string, OpenApiPathItem> path in openApiDocument.Paths)\n                {\n                    string relativeUrl = path.Key;\n\n                    EndpointMetadata endpointMetadata = ReadOperations(relativeUrl, path.Value.Operations);\n\n                    metadata.Add(endpointMetadata);\n                }\n            }\n\n            return metadata;\n        }\n\n        private static EndpointMetadata ReadOperations(string path, IDictionary<OperationType, OpenApiOperation> operations)\n        {\n            EndpointMetadata endpointMetadata = new EndpointMetadata(path);\n\n            if (operations is not null)\n            {\n                foreach (KeyValuePair<OperationType, OpenApiOperation> operation in operations)\n                {\n                    RequestMetadata requestMetadata = new RequestMetadata(operation.Key);\n\n                    foreach (OpenApiParameter parameter in operation.Value.Parameters)\n                    {\n                        requestMetadata.Parameters.Add(parameter);\n                    }\n\n                    if (operation.Value.RequestBody?.Content is not null)\n                    {\n                        foreach (KeyValuePair<string, OpenApiMediaType> content in operation.Value.RequestBody.Content)\n                        {\n                            string contentType = content.Key;\n                            bool isRequired = operation.Value.RequestBody.Required;\n                            OpenApiSchema? schema = content.Value?.Schema;\n\n                            requestMetadata.Content.Add(new RequestContentMetadata(contentType, isRequired, schema));\n                        }\n                    }\n\n                    endpointMetadata.AvailableRequests.Add(requestMetadata);\n                }\n            }\n\n            return endpointMetadata;\n        }\n\n        private static DirectoryStructure BuildDirectoryStructure(IList<EndpointMetadata> metadata)\n        {\n            DirectoryStructure d = new DirectoryStructure(null);\n\n            if (metadata is not null)\n            {\n                for (int index = 0; index < metadata.Count; index++)\n                {\n                    System.Diagnostics.Debug.WriteLine(index);\n                    EndpointMetadata entry = metadata[index];\n                    ApiDefinitionReader.FillDirectoryInfo(d, entry);\n                }\n            }\n\n            return d;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/OpenApi/SchemaDataGenerator.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing Microsoft.OpenApi.Models;\nusing Newtonsoft.Json.Linq;\n\nnamespace Microsoft.HttpRepl.OpenApi\n{\n    internal static class SchemaDataGenerator\n    {\n        // TODO: Make this a setting?\n        private const int MaxExampleDataDepth = 3;\n\n        public static string GetBodyString(OpenApiSchema schema)\n        {\n            if (schema is not null)\n            {\n                JToken result = GenerateData(schema);\n                return result?.ToString() ?? \"{\\n}\";\n            }\n\n            return null;\n        }\n\n        internal static JToken GenerateData(OpenApiSchema schema, int depth = 0)\n        {\n            if (schema is null)\n            {\n                return null;\n            }\n\n            if (schema.Example is not null)\n            {\n                return JToken.FromObject(schema.Example);\n            }\n\n            if (schema.Default is not null)\n            {\n                return JToken.FromObject(schema.Default);\n            }\n\n            if (schema.Type is null)\n            {\n                if (schema.Properties is not null || schema.AdditionalProperties is not null || schema.MinProperties.HasValue || schema.MaxProperties.HasValue)\n                {\n                    schema.Type = \"OBJECT\";\n                }\n                else if (schema.Items is not null || schema.MinItems.HasValue || schema.MaxItems.HasValue)\n                {\n                    schema.Type = \"ARRAY\";\n                }\n                else if (schema.Minimum.HasValue || schema.Maximum.HasValue || schema.MultipleOf.HasValue)\n                {\n                    schema.Type = \"INTEGER\";\n                }\n            }\n\n            switch (schema.Type?.ToUpperInvariant())\n            {\n                case null:\n                case \"STRING\":\n                    if (string.Equals(schema.Format, \"date-time\", StringComparison.OrdinalIgnoreCase))\n                    {\n                        return DateTimeOffset.Now.ToString(\"o\");\n                    }\n                    return \"\";\n                case \"NUMBER\":\n                    if (schema.Minimum.HasValue)\n                    {\n                        if (schema.Maximum.HasValue)\n                        {\n                            return (schema.Maximum.Value + schema.Minimum.Value) / 2;\n                        }\n\n                        if (schema.ExclusiveMinimum is true)\n                        {\n                            return schema.Minimum.Value + 1;\n                        }\n\n                        return schema.Minimum.Value;\n                    }\n                    return 1.1;\n                case \"INTEGER\":\n                    if (schema.Minimum.HasValue)\n                    {\n                        if (schema.Maximum.HasValue)\n                        {\n                            return (int)((schema.Maximum.Value + schema.Minimum.Value) / 2);\n                        }\n\n                        if (schema.ExclusiveMinimum is true)\n                        {\n                            return schema.Minimum.Value + 1;\n                        }\n\n                        return schema.Minimum.Value;\n                    }\n                    return 0;\n                case \"BOOLEAN\":\n                    return true;\n                case \"ARRAY\":\n                    JArray container = new JArray();\n\n                    if (depth < MaxExampleDataDepth)\n                    {\n                        JToken item = GenerateData(schema.Items, depth + 1) ?? \"\";\n\n                        int count = schema.MinItems.GetValueOrDefault();\n                        count = Math.Max(1, count);\n\n                        for (int i = 0; i < count; ++i)\n                        {\n                            container.Add(item.DeepClone());\n                        }\n                    }\n\n                    return container;\n                case \"OBJECT\":\n                    if (schema.Properties is not null)\n                    {\n                        JObject obj = new JObject();\n                        if (depth < MaxExampleDataDepth)\n                        {\n                            foreach (KeyValuePair<string, OpenApiSchema> property in schema.Properties)\n                            {\n                                if (property.Value.ReadOnly)\n                                {\n                                    continue;\n                                }\n\n                                JToken data = GenerateData(property.Value, depth + 1) ?? \"\";\n                                obj[property.Key] = data;\n                            }\n                        }\n                        return obj;\n                    }\n                    return null;\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Preferences/IJsonConfig.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Preferences\n{\n    public interface IJsonConfig\n    {\n        int IndentSize { get; }\n\n        AllowedColors DefaultColor { get; }\n\n        AllowedColors ArrayBraceColor { get; }\n\n        AllowedColors ObjectBraceColor { get; }\n\n        AllowedColors CommaColor { get; }\n\n        AllowedColors NameColor { get; }\n\n        AllowedColors NameSeparatorColor { get; }\n\n        AllowedColors BoolColor { get; }\n\n        AllowedColors NumericColor { get; }\n\n        AllowedColors StringColor { get; }\n\n        AllowedColors NullColor { get; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Preferences/IPreferences.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Preferences\n{\n    public interface IPreferences\n    {\n        AllowedColors GetColorValue(string preference, AllowedColors defaultValue = AllowedColors.None);\n        int GetIntValue(string preference, int defaultValue = default);\n        bool GetBoolValue(string preference, bool defaultValue = default);\n        string GetValue(string preference, string defaultValue = default);\n        bool TryGetValue(string preference, out string value);\n        bool SetValue(string preference, string value);\n        IReadOnlyDictionary<string, string> DefaultPreferences { get; }\n        IReadOnlyDictionary<string, string> CurrentPreferences { get; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Preferences/JsonConfig.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Preferences\n{\n    public class JsonConfig : IJsonConfig\n    {\n        private readonly IPreferences _preferences;\n\n        public int IndentSize => _preferences.GetIntValue(WellKnownPreference.JsonIndentSize, 2);\n\n        public AllowedColors DefaultColor => _preferences.GetColorValue(WellKnownPreference.JsonColor);\n\n        private AllowedColors DefaultBraceColor => _preferences.GetColorValue(WellKnownPreference.JsonBraceColor, DefaultSyntaxColor);\n\n        private AllowedColors DefaultSyntaxColor => _preferences.GetColorValue(WellKnownPreference.JsonSyntaxColor, DefaultColor);\n\n        private AllowedColors DefaultLiteralColor => _preferences.GetColorValue(WellKnownPreference.JsonLiteralColor, DefaultColor);\n\n        public AllowedColors ArrayBraceColor => _preferences.GetColorValue(WellKnownPreference.JsonArrayBraceColor, DefaultBraceColor);\n\n        public AllowedColors ObjectBraceColor => _preferences.GetColorValue(WellKnownPreference.JsonObjectBraceColor, DefaultBraceColor);\n\n        public AllowedColors CommaColor => _preferences.GetColorValue(WellKnownPreference.JsonCommaColor, DefaultSyntaxColor);\n\n        public AllowedColors NameColor => _preferences.GetColorValue(WellKnownPreference.JsonNameColor, StringColor);\n\n        public AllowedColors NameSeparatorColor => _preferences.GetColorValue(WellKnownPreference.JsonNameSeparatorColor, DefaultSyntaxColor);\n\n        public AllowedColors BoolColor => _preferences.GetColorValue(WellKnownPreference.JsonBoolColor, DefaultLiteralColor);\n\n        public AllowedColors NumericColor => _preferences.GetColorValue(WellKnownPreference.JsonNumericColor, DefaultLiteralColor);\n\n        public AllowedColors StringColor => _preferences.GetColorValue(WellKnownPreference.JsonStringColor, DefaultLiteralColor);\n\n        public AllowedColors NullColor => _preferences.GetColorValue(WellKnownPreference.JsonNullColor, DefaultLiteralColor);\n\n        public JsonConfig(IPreferences preferences)\n        {\n            _preferences = preferences;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Preferences/OpenApiSearchPathsProvider.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.txt file in the project root for more information.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.HttpRepl.OpenApi;\n\nnamespace Microsoft.HttpRepl.Preferences\n{\n    internal sealed class OpenApiSearchPathsProvider : IOpenApiSearchPathsProvider\n    {\n        // OpenAPI description search paths are appended to the base url to\n        // attempt to find the description document. A search path is a\n        // relative url that is appended to the base url using Uri.TryCreate,\n        // so the semantics of relative urls matter here.\n        // Example: Base path https://localhost/v1/ and search path openapi.json\n        //          will result in https://localhost/v1/openapi.json being tested.\n        // Example: Base path https://localhost/v1/ and search path /openapi.json\n        //          will result in https://localhost/openapi.json being tested.\n        internal static IEnumerable<string> DefaultSearchPaths { get; } = new[] {\n            \"swagger.json\",\n            \"/swagger.json\",\n            \"swagger/v1/swagger.json\",\n            \"/swagger/v1/swagger.json\",\n            \"openapi.json\",\n            \"/openapi.json\",\n        };\n\n        private readonly IPreferences _preferences;\n        public OpenApiSearchPathsProvider(IPreferences preferences)\n        {\n            _preferences = preferences ?? throw new ArgumentNullException(nameof(preferences));\n        }\n\n        public IEnumerable<string> GetOpenApiSearchPaths()\n        {\n            string[] configSearchPaths = Split(_preferences.GetValue(WellKnownPreference.SwaggerSearchPaths));\n\n            if (configSearchPaths.Length > 0)\n            {\n                return configSearchPaths;\n            }\n\n            string[] addToSearchPaths = Split(_preferences.GetValue(WellKnownPreference.SwaggerAddToSearchPaths));\n            string[] removeFromSearchPaths = Split(_preferences.GetValue(WellKnownPreference.SwaggerRemoveFromSearchPaths));\n\n            return DefaultSearchPaths.Union(addToSearchPaths).Except(removeFromSearchPaths);\n        }\n\n        private static string[] Split(string searchPaths)\n        {\n            if (string.IsNullOrWhiteSpace(searchPaths))\n            {\n                return Array.Empty<string>();\n            }\n            else\n            {\n                return searchPaths.Split('|', StringSplitOptions.RemoveEmptyEntries);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Preferences/RequestConfig.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Preferences\n{\n    public class RequestConfig : RequestOrResponseConfig\n    {\n        public RequestConfig(IPreferences preferences)\n            : base(preferences)\n        {\n        }\n\n        public override AllowedColors BodyColor => Preferences.GetColorValue(WellKnownPreference.RequestBodyColor, base.BodyColor);\n\n        public override AllowedColors SchemeColor => Preferences.GetColorValue(WellKnownPreference.RequestSchemeColor, base.SchemeColor);\n\n        public override AllowedColors HeaderKeyColor => Preferences.GetColorValue(WellKnownPreference.RequestHeaderKeyColor, base.HeaderKeyColor);\n\n        public override AllowedColors HeaderSeparatorColor => Preferences.GetColorValue(WellKnownPreference.RequestHeaderSeparatorColor, base.HeaderSeparatorColor);\n\n        public override AllowedColors HeaderValueSeparatorColor => Preferences.GetColorValue(WellKnownPreference.RequestHeaderValueSeparatorColor, base.HeaderValueSeparatorColor);\n\n        public override AllowedColors HeaderValueColor => Preferences.GetColorValue(WellKnownPreference.RequestHeaderValueColor, base.HeaderValueColor);\n\n        public override AllowedColors HeaderColor => Preferences.GetColorValue(WellKnownPreference.RequestHeaderColor, base.HeaderColor);\n\n        public override AllowedColors GeneralColor => Preferences.GetColorValue(WellKnownPreference.RequestColor, base.GeneralColor);\n\n        public override AllowedColors ProtocolColor => Preferences.GetColorValue(WellKnownPreference.RequestProtocolColor, base.ProtocolColor);\n\n        public override AllowedColors ProtocolNameColor => Preferences.GetColorValue(WellKnownPreference.RequestProtocolNameColor, base.ProtocolNameColor);\n\n        public override AllowedColors ProtocolVersionColor => Preferences.GetColorValue(WellKnownPreference.RequestProtocolVersionColor, base.ProtocolVersionColor);\n\n        public override AllowedColors ProtocolSeparatorColor => Preferences.GetColorValue(WellKnownPreference.RequestProtocolSeparatorColor, base.ProtocolSeparatorColor);\n\n        public override AllowedColors StatusColor => Preferences.GetColorValue(WellKnownPreference.RequestStatusColor, base.StatusColor);\n\n        public override AllowedColors StatusCodeColor => Preferences.GetColorValue(WellKnownPreference.RequestStatusCodeColor, base.StatusCodeColor);\n\n        public override AllowedColors StatusReasonPhraseColor => Preferences.GetColorValue(WellKnownPreference.RequestStatusReaseonPhraseColor, base.StatusReasonPhraseColor);\n\n        public AllowedColors MethodColor => Preferences.GetColorValue(WellKnownPreference.RequestMethodColor, GeneralColor);\n\n        public AllowedColors AddressColor => Preferences.GetColorValue(WellKnownPreference.RequestAddressColor, GeneralColor);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Preferences/RequestOrResponseConfig.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Preferences\n{\n    public abstract class RequestOrResponseConfig\n    {\n        protected IPreferences Preferences { get; }\n\n        protected RequestOrResponseConfig(IPreferences preferences)\n        {\n            Preferences = preferences;\n        }\n\n        public virtual AllowedColors BodyColor => Preferences.GetColorValue(WellKnownPreference.BodyColor, GeneralColor);\n\n        public virtual AllowedColors SchemeColor => Preferences.GetColorValue(WellKnownPreference.SchemeColor, GeneralColor);\n\n        public virtual AllowedColors HeaderKeyColor => Preferences.GetColorValue(WellKnownPreference.HeaderKeyColor, HeaderColor);\n\n        public virtual AllowedColors HeaderSeparatorColor => Preferences.GetColorValue(WellKnownPreference.HeaderSeparatorColor, HeaderColor);\n\n        public virtual AllowedColors HeaderValueSeparatorColor => Preferences.GetColorValue(WellKnownPreference.HeaderValueSeparatorColor, HeaderSeparatorColor);\n\n        public virtual AllowedColors HeaderValueColor => Preferences.GetColorValue(WellKnownPreference.HeaderValueColor, HeaderColor);\n\n        public virtual AllowedColors HeaderColor => Preferences.GetColorValue(WellKnownPreference.HeaderColor, GeneralColor);\n\n        public virtual AllowedColors GeneralColor => Preferences.GetColorValue(WellKnownPreference.RequestOrResponseColor);\n\n        public virtual AllowedColors ProtocolColor => Preferences.GetColorValue(WellKnownPreference.ProtocolColor, GeneralColor);\n\n        public virtual AllowedColors ProtocolNameColor => Preferences.GetColorValue(WellKnownPreference.ProtocolNameColor, ProtocolColor);\n\n        public virtual AllowedColors ProtocolVersionColor => Preferences.GetColorValue(WellKnownPreference.ProtocolVersionColor, ProtocolColor);\n\n        public virtual AllowedColors ProtocolSeparatorColor => Preferences.GetColorValue(WellKnownPreference.ProtocolSeparatorColor, ProtocolColor);\n\n        public virtual AllowedColors StatusColor => Preferences.GetColorValue(WellKnownPreference.StatusColor, GeneralColor);\n\n        public virtual AllowedColors StatusCodeColor => Preferences.GetColorValue(WellKnownPreference.StatusCodeColor, StatusColor);\n\n        public virtual AllowedColors StatusReasonPhraseColor => Preferences.GetColorValue(WellKnownPreference.StatusReaseonPhraseColor, StatusColor);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Preferences/ResponseConfig.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Preferences\n{\n    public class ResponseConfig : RequestOrResponseConfig\n    {\n        public ResponseConfig(IPreferences preferences)\n            : base(preferences)\n        {\n        }\n\n        public override AllowedColors BodyColor => Preferences.GetColorValue(WellKnownPreference.ResponseBodyColor, base.BodyColor);\n\n        public override AllowedColors SchemeColor => Preferences.GetColorValue(WellKnownPreference.ResponseSchemeColor, base.SchemeColor);\n\n        public override AllowedColors HeaderKeyColor => Preferences.GetColorValue(WellKnownPreference.ResponseHeaderKeyColor, base.HeaderKeyColor);\n\n        public override AllowedColors HeaderSeparatorColor => Preferences.GetColorValue(WellKnownPreference.ResponseHeaderSeparatorColor, base.HeaderSeparatorColor);\n\n        public override AllowedColors HeaderValueSeparatorColor => Preferences.GetColorValue(WellKnownPreference.ResponseHeaderValueSeparatorColor, base.HeaderValueSeparatorColor);\n\n        public override AllowedColors HeaderValueColor => Preferences.GetColorValue(WellKnownPreference.ResponseHeaderValueColor, base.HeaderValueColor);\n\n        public override AllowedColors HeaderColor => Preferences.GetColorValue(WellKnownPreference.ResponseHeaderColor, base.HeaderColor);\n\n        public override AllowedColors GeneralColor => Preferences.GetColorValue(WellKnownPreference.ResponseColor, base.GeneralColor);\n\n        public override AllowedColors ProtocolColor => Preferences.GetColorValue(WellKnownPreference.ResponseProtocolColor, base.ProtocolColor);\n\n        public override AllowedColors ProtocolNameColor => Preferences.GetColorValue(WellKnownPreference.ResponseProtocolNameColor, base.ProtocolNameColor);\n\n        public override AllowedColors ProtocolVersionColor => Preferences.GetColorValue(WellKnownPreference.ResponseProtocolVersionColor, base.ProtocolVersionColor);\n\n        public override AllowedColors ProtocolSeparatorColor => Preferences.GetColorValue(WellKnownPreference.ResponseProtocolSeparatorColor, base.ProtocolSeparatorColor);\n\n        public override AllowedColors StatusColor => Preferences.GetColorValue(WellKnownPreference.ResponseStatusColor, base.StatusColor);\n\n        public override AllowedColors StatusCodeColor => Preferences.GetColorValue(WellKnownPreference.ResponseStatusCodeColor, base.StatusCodeColor);\n\n        public override AllowedColors StatusReasonPhraseColor => Preferences.GetColorValue(WellKnownPreference.ResponseStatusReaseonPhraseColor, base.StatusReasonPhraseColor);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Preferences/UserFolderPreferences.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.IO;\nusing System.Linq;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.UserProfile;\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Preferences\n{\n    public class UserFolderPreferences : IPreferences\n    {\n        private string _prefsFilePath;\n        private readonly IFileSystem _fileSystem;\n        private readonly IUserProfileDirectoryProvider _userProfileDirectoryProvider;\n\n        private Dictionary<string, string> _preferences;\n\n        private Dictionary<string, string> Preferences\n        {\n            get\n            {\n                if (_preferences == null)\n                {\n                    _preferences = ReadPreferences(DefaultPreferences);\n                }\n\n                return _preferences;\n            }\n        }\n\n        public IReadOnlyDictionary<string, string> DefaultPreferences { get; }\n\n        public string PreferencesFilePath\n        {\n            get\n            {\n                if (_prefsFilePath == null)\n                {\n                    string userProfileDirectory = _userProfileDirectoryProvider.GetUserProfileDirectory();\n                    _prefsFilePath = Path.Combine(userProfileDirectory, \".httpreplprefs\");\n                }\n                return _prefsFilePath;\n            }\n        }\n\n        public UserFolderPreferences(IFileSystem fileSystem, IUserProfileDirectoryProvider userProfileDirectoryProvider, IDictionary<string, string> defaultPreferences)\n        {\n            _fileSystem = fileSystem;\n            _userProfileDirectoryProvider = userProfileDirectoryProvider;\n            DefaultPreferences = SetupDefaults(defaultPreferences);\n        }\n\n        public AllowedColors GetColorValue(string preference, AllowedColors defaultValue = AllowedColors.None)\n        {\n            if (!Preferences.TryGetValue(preference, out string preferenceValueString) || !Enum.TryParse(preferenceValueString, true, out AllowedColors result))\n            {\n                result = defaultValue;\n            }\n\n            return result;\n        }\n\n        public int GetIntValue(string preference, int defaultValue)\n        {\n            if (!Preferences.TryGetValue(preference, out string preferenceValueString) || !int.TryParse(preferenceValueString, out int result))\n            {\n                result = defaultValue;\n            }\n\n            return result;\n        }\n\n        public bool GetBoolValue(string preference, bool defaultValue)\n        {\n            if (!Preferences.TryGetValue(preference, out string preferenceValueString) || !bool.TryParse(preferenceValueString, out bool result))\n            {\n                result = defaultValue;\n            }\n\n            return result;\n        }\n\n        public string GetValue(string preference, string defaultValue = default)\n        {\n            if (!Preferences.TryGetValue(preference, out string result))\n            {\n                result = defaultValue;\n            }\n\n            return result;\n        }\n\n        public bool TryGetValue(string preference, out string value)\n        {\n            return Preferences.TryGetValue(preference, out value);\n        }\n\n        public bool SetValue(string preference, string value)\n        {\n            if (string.IsNullOrEmpty(value))\n            {\n                if (!DefaultPreferences.TryGetValue(preference, out string defaultValue))\n                {\n                    Preferences.Remove(preference);\n                }\n                else\n                {\n                    Preferences[preference] = defaultValue;\n                }\n            }\n            else\n            {\n                Preferences[preference] = value;\n            }\n\n            return WritePreferences(Preferences, DefaultPreferences);\n        }\n\n        public IReadOnlyDictionary<string, string> CurrentPreferences\n        {\n            get\n            {\n                return new ReadOnlyDictionary<string, string>(Preferences);\n            }\n        }\n\n        private Dictionary<string, string> ReadPreferences(IReadOnlyDictionary<string, string> defaultPreferences)\n        {\n            Dictionary<string, string> preferences = new Dictionary<string, string>(defaultPreferences);\n\n            if (_fileSystem.FileExists(PreferencesFilePath))\n            {\n                string[] prefsFile = _fileSystem.ReadAllLinesFromFile(PreferencesFilePath);\n\n                foreach (string line in prefsFile)\n                {\n                    int equalsIndex = line.IndexOf('=', StringComparison.Ordinal);\n\n                    // If there's no = or = is the first character on the line\n                    // (meaning no preference name), move to the next line\n                    if (equalsIndex <= 0)\n                    {\n                        continue;\n                    }\n\n                    preferences[line.Substring(0, equalsIndex)] = line.Substring(equalsIndex + 1);\n                }\n            }\n\n            return preferences;\n        }\n\n        private bool WritePreferences(Dictionary<string, string> preferences, IReadOnlyDictionary<string, string> defaultPreferences)\n        {\n            List<string> lines = new List<string>();\n            foreach (KeyValuePair<string, string> entry in preferences.OrderBy(x => x.Key))\n            {\n                //If the value didn't exist in the defaults or the value's different, include it in the user's preferences file\n                if (!defaultPreferences.TryGetValue(entry.Key, out string value) || !string.Equals(value, entry.Value, StringComparison.Ordinal))\n                {\n                    lines.Add($\"{entry.Key}={entry.Value}\");\n                }\n            }\n\n            try\n            {\n                _fileSystem.WriteAllLinesToFile(PreferencesFilePath, lines);\n                return true;\n            }\n            catch\n            {\n                return false;\n            }\n        }\n\n        private static IReadOnlyDictionary<string, string> SetupDefaults(IDictionary<string, string> defaults)\n        {\n            Dictionary<string, string> tempDictionary = new Dictionary<string, string>();\n\n            if (defaults != null)\n            {\n                foreach (KeyValuePair<string, string> kvp in defaults)\n                {\n                    tempDictionary.Add(kvp.Key, kvp.Value);\n                }\n            }\n\n            return new ReadOnlyDictionary<string, string>(tempDictionary);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Preferences/WellKnownPreference.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Reflection;\n\nnamespace Microsoft.HttpRepl.Preferences\n{\n    public static class WellKnownPreference\n    {\n        public static class Catalog\n        {\n            private static IReadOnlyList<string> _names;\n\n            public static IReadOnlyList<string> Names\n            {\n                get\n                {\n                    if (_names != null)\n                    {\n                        return _names;\n                    }\n\n                    List<string> matchingProperties = new List<string>();\n\n                    foreach (PropertyInfo property in typeof(WellKnownPreference).GetProperties(BindingFlags.Public | BindingFlags.Static))\n                    {\n                        if (property.PropertyType == typeof(string) && property.GetMethod != null && property.GetValue(null) is string val)\n                        {\n                            matchingProperties.Add(val);\n                        }\n                    }\n\n                    return _names = matchingProperties;\n                }\n            }\n        }\n\n        public static string JsonArrayBraceColor { get; } = \"colors.json.arrayBrace\";\n\n        public static string JsonObjectBraceColor { get; } = \"colors.json.objectBrace\";\n\n        public static string JsonNameColor { get; } = \"colors.json.name\";\n\n        public static string JsonNameSeparatorColor { get; } = \"colors.json.nameSeparator\";\n\n        public static string JsonIndentSize { get; } = \"formatting.json.indentSize\";\n\n        public static string JsonCommaColor { get; } = \"colors.json.comma\";\n\n        public static string JsonLiteralColor { get; } = \"colors.json.literal\";\n\n        public static string JsonNullColor { get; } = \"colors.json.null\";\n\n        public static string JsonBoolColor { get; } = \"colors.json.bool\";\n\n        public static string JsonNumericColor { get; } = \"colors.json.numeric\";\n\n        public static string JsonStringColor { get; } = \"colors.json.string\";\n\n        public static string JsonColor { get; } = \"colors.json\";\n\n        public static string JsonSyntaxColor { get; } = \"colors.json.syntax\";\n\n        public static string JsonBraceColor { get; } = \"colors.json.brace\";\n\n        public static string RequestColor { get; } = \"colors.request\";\n\n        public static string RequestBodyColor { get; } = \"colors.request.body\";\n\n        public static string RequestSchemeColor { get; } = \"colors.request.scheme\";\n\n        public static string RequestHeaderKeyColor { get; } = \"colors.request.header.key\";\n\n        public static string RequestHeaderSeparatorColor { get; } = \"colors.request.header.separator\";\n\n        public static string RequestHeaderValueSeparatorColor { get; } = \"colors.request.header.valueSeparator\";\n\n        public static string RequestHeaderValueColor { get; } = \"colors.request.header.value\";\n\n        public static string RequestHeaderColor { get; } = \"colors.request.header\";\n\n        public static string RequestProtocolColor { get; } = \"colors.request.protocol\";\n\n        public static string RequestProtocolNameColor { get; } = \"colors.request.protocol.name\";\n\n        public static string RequestProtocolSeparatorColor { get; } = \"colors.request.protocol.separator\";\n\n        public static string RequestProtocolVersionColor { get; } = \"colors.request.protocol.version\";\n\n        public static string RequestStatusColor { get; } = \"colors.request.status\";\n\n        public static string RequestStatusCodeColor { get; } = \"colors.request.status.code\";\n\n        public static string RequestStatusReaseonPhraseColor { get; } = \"colors.request.status.reasonPhrase\";\n\n        public static string RequestMethodColor { get; } = \"colors.request.method\";\n\n        public static string RequestAddressColor { get; } = \"colors.request.address\";\n\n\n        public static string ResponseColor { get; } = \"colors.response\";\n\n        public static string ResponseBodyColor { get; } = \"colors.response.body\";\n\n        public static string ResponseSchemeColor { get; } = \"colors.response.scheme\";\n\n        public static string ResponseHeaderKeyColor { get; } = \"colors.response.header.key\";\n\n        public static string ResponseHeaderSeparatorColor { get; } = \"colors.response.header.separator\";\n\n        public static string ResponseHeaderValueSeparatorColor { get; } = \"colors.response.header.valueSeparator\";\n\n        public static string ResponseHeaderValueColor { get; } = \"colors.response.header.value\";\n\n        public static string ResponseHeaderColor { get; } = \"colors.response.header\";\n\n        public static string ResponseProtocolColor { get; } = \"colors.response.protocol\";\n\n        public static string ResponseProtocolNameColor { get; } = \"colors.response.protocol.name\";\n\n        public static string ResponseProtocolSeparatorColor { get; } = \"colors.response.protocol.separator\";\n\n        public static string ResponseProtocolVersionColor { get; } = \"colors.response.protocol.version\";\n\n        public static string ResponseStatusColor { get; } = \"colors.response.status\";\n\n        public static string ResponseStatusCodeColor { get; } = \"colors.response.status.code\";\n\n        public static string ResponseStatusReaseonPhraseColor { get; } = \"colors.response.status.reasonPhrase\";\n\n        public static string RequestOrResponseColor { get; } = \"colors.requestOrResponse\";\n\n        public static string ErrorColor { get; } = \"colors.error\";\n\n        public static string WarningColor { get; } = \"colors.warning\";\n\n        public static string BodyColor { get; } = \"colors.body\";\n\n        public static string SchemeColor { get; } = \"colors.scheme\";\n\n        public static string HeaderKeyColor { get; } = \"colors.header.key\";\n\n        public static string HeaderSeparatorColor { get; } = \"colors.header.separator\";\n\n        public static string HeaderValueSeparatorColor { get; } = \"colors.header.valueSeparator\";\n\n        public static string HeaderValueColor { get; } = \"colors.header.value\";\n\n        public static string HeaderColor { get; } = \"colors.header\";\n\n        public static string ProtocolColor { get; } = \"colors.protocol\";\n\n        public static string ProtocolNameColor { get; } = \"colors.protocol.name\";\n\n        public static string ProtocolSeparatorColor { get; } = \"colors.protocol.separator\";\n\n        public static string ProtocolVersionColor { get; } = \"colors.protocol.version\";\n\n        public static string StatusColor { get; } = \"colors.status\";\n\n        public static string StatusCodeColor { get; } = \"colors.status.code\";\n\n        public static string StatusReaseonPhraseColor { get; } = \"colors.status.reasonPhrase\";\n\n\n        public static string DefaultEditorCommand { get; } = \"editor.command.default\";\n\n        public static string DefaultEditorArguments { get; } = \"editor.command.default.arguments\";\n\n        public static string SwaggerRequeryBehavior { get; } = \"swagger.requery\";\n\n        public static string SwaggerSearchPaths { get; } = \"swagger.searchPaths\";\n\n        public static string SwaggerUIEndpoint { get; } = \"swagger.uiEndpoint\";\n\n        public static string SwaggerRemoveFromSearchPaths => \"swagger.removeFromSearchPaths\";\n\n        public static string SwaggerAddToSearchPaths => \"swagger.addToSearchPaths\";\n\n        public static string UseDefaultCredentials { get; } = \"httpClient.useDefaultCredentials\";\n\n        public static string HttpClientUserAgent { get; } = \"httpClient.userAgent\";\n\n        public static string ProxyUseDefaultCredentials => \"httpClient.proxy.useDefaultCredentials\";\n\n        public static string ConnectCommandSkipRootFix => \"connectCommand.skipRootFix\";\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Program.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.HttpRepl.UserProfile;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl\n{\n    public static class Program\n    {\n        public static async Task Main(string[] args)\n        {\n            await Start(args);\n        }\n\n        public static async Task Start(string[] args, IConsoleManager consoleManager = null, IPreferences preferences = null, ITelemetry telemetry = null)\n        {\n            args = args ?? throw new ArgumentNullException(nameof(args));\n\n            RegisterEncodingProviders();\n            ComposeDependencies(ref consoleManager, ref preferences, ref telemetry, out HttpState state, out Shell shell);\n\n            if (!telemetry.FirstTimeUseNoticeSentinel.Exists() && !Telemetry.Telemetry.SkipFirstTimeExperience)\n            {\n                Reporter.Output.WriteLine(string.Format(Resources.Strings.Telemetry_WelcomeMessage, VersionSensor.AssemblyVersion.ToString(2)));\n                telemetry.FirstTimeUseNoticeSentinel.CreateIfNotExists();\n            }\n\n            if (Console.IsOutputRedirected && !consoleManager.AllowOutputRedirection)\n            {\n                telemetry.TrackStartedEvent(withOutputRedirection: true);\n                Reporter.Error.WriteLine(Resources.Strings.Error_OutputRedirected.SetColor(preferences.GetColorValue(WellKnownPreference.ErrorColor)));\n                return;\n            }\n\n            using (CancellationTokenSource source = new CancellationTokenSource())\n            {\n                shell.ShellState.ConsoleManager.AddBreakHandler(() => source.Cancel());\n                if (args.Length > 0)\n                {\n                    if (string.Equals(args[0], \"--help\", StringComparison.OrdinalIgnoreCase) || string.Equals(args[0], \"-h\", StringComparison.OrdinalIgnoreCase))\n                    {\n                        telemetry.TrackStartedEvent(withHelp: true);\n                        shell.ShellState.ConsoleManager.WriteLine(Resources.Strings.Help_Usage);\n                        shell.ShellState.ConsoleManager.WriteLine(\"  httprepl [<BASE_ADDRESS>] [options]\");\n                        shell.ShellState.ConsoleManager.WriteLine();\n                        shell.ShellState.ConsoleManager.WriteLine(Resources.Strings.Help_Arguments);\n                        shell.ShellState.ConsoleManager.WriteLine(string.Format(Resources.Strings.Help_BaseAddress, \"<BASE_ADDRESS>\"));\n                        shell.ShellState.ConsoleManager.WriteLine();\n                        shell.ShellState.ConsoleManager.WriteLine(Resources.Strings.Help_Options);\n                        shell.ShellState.ConsoleManager.WriteLine(string.Format(Resources.Strings.Help_Help, \"-h|--help\"));\n\n                        shell.ShellState.ConsoleManager.WriteLine();\n                        shell.ShellState.ConsoleManager.WriteLine(Resources.Strings.Help_REPLCommands);\n                        HelpCommand.CoreGetHelp(shell.ShellState, (ICommandDispatcher<HttpState, ICoreParseResult>)shell.ShellState.CommandDispatcher, state);\n                        return;\n                    }\n\n                    // allow running a script file directly.\n                    if (string.Equals(args[0], \"run\", StringComparison.OrdinalIgnoreCase))\n                    {\n                        telemetry.TrackStartedEvent(withRun: true);\n                        shell.ShellState.CommandDispatcher.OnReady(shell.ShellState);\n                        shell.ShellState.InputManager.SetInput(shell.ShellState, string.Join(' ', args));\n                        await shell.ShellState.CommandDispatcher.ExecuteCommandAsync(shell.ShellState, CancellationToken.None).ConfigureAwait(false);\n                        return;\n                    }\n\n                    telemetry.TrackStartedEvent(withOtherArgs: args.Length > 0);\n\n                    string combinedArgs = string.Join(' ', args);\n\n                    shell.ShellState.CommandDispatcher.OnReady(shell.ShellState);\n                    shell.ShellState.InputManager.SetInput(shell.ShellState, $\"connect {combinedArgs}\");\n                    await shell.ShellState.CommandDispatcher.ExecuteCommandAsync(shell.ShellState, CancellationToken.None).ConfigureAwait(false);\n                }\n                else\n                {\n                    telemetry.TrackStartedEvent();\n                }\n\n                await shell.RunAsync(source.Token).ConfigureAwait(false);\n            }\n        }\n\n        private static void ComposeDependencies(ref IConsoleManager consoleManager, ref IPreferences preferences, ref ITelemetry telemetry, out HttpState state, out Shell shell)\n        {\n            consoleManager ??= new ConsoleManager();\n            IFileSystem fileSystem = new RealFileSystem();\n            preferences ??= new UserFolderPreferences(fileSystem, new UserProfileDirectoryProvider(), CreateDefaultPreferences());\n            telemetry ??= new Telemetry.Telemetry(VersionSensor.AssemblyInformationalVersion);\n            HttpClient httpClient = GetHttpClientWithPreferences(preferences);\n            state = new HttpState(preferences, httpClient);\n\n            DefaultCommandDispatcher<HttpState> dispatcher = DefaultCommandDispatcher.Create(state.GetPrompt, state);\n            dispatcher.AddCommandWithTelemetry(telemetry, new ChangeDirectoryCommand());\n            dispatcher.AddCommandWithTelemetry(telemetry, new ClearCommand());\n            dispatcher.AddCommandWithTelemetry(telemetry, new ClearQueryParamCommand(telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new ConnectCommand(preferences, telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new DeleteCommand(fileSystem, preferences, telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new EchoCommand());\n            dispatcher.AddCommandWithTelemetry(telemetry, new ExitCommand());\n            dispatcher.AddCommandWithTelemetry(telemetry, new HeadCommand(fileSystem, preferences, telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new HelpCommand());\n            dispatcher.AddCommandWithTelemetry(telemetry, new GetCommand(fileSystem, preferences, telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new ListCommand(preferences));\n            dispatcher.AddCommandWithTelemetry(telemetry, new OptionsCommand(fileSystem, preferences, telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new PatchCommand(fileSystem, preferences, telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new PrefCommand(preferences, telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new PostCommand(fileSystem, preferences, telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new PutCommand(fileSystem, preferences, telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new RunCommand(fileSystem));\n            dispatcher.AddCommandWithTelemetry(telemetry, new SetHeaderCommand(telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new AddQueryParamCommand(telemetry));\n            dispatcher.AddCommandWithTelemetry(telemetry, new UICommand(new UriLauncher(), preferences));\n\n            shell = new Shell(dispatcher, consoleManager: consoleManager);\n        }\n\n        internal static Dictionary<string, string> CreateDefaultPreferences()\n        {\n            return new Dictionary<string, string>\n            {\n                { WellKnownPreference.ProtocolColor, \"BoldGreen\" },\n                { WellKnownPreference.StatusColor, \"BoldYellow\" },\n\n                { WellKnownPreference.JsonArrayBraceColor, \"BoldCyan\" },\n                { WellKnownPreference.JsonCommaColor, \"BoldYellow\" },\n                { WellKnownPreference.JsonNameColor, \"BoldMagenta\" },\n                { WellKnownPreference.JsonNameSeparatorColor, \"BoldWhite\" },\n                { WellKnownPreference.JsonObjectBraceColor, \"Cyan\" },\n                { WellKnownPreference.JsonColor, \"Green\" }\n            };\n        }\n\n        private static HttpClient GetHttpClientWithPreferences(IPreferences preferences)\n        {\n            bool useDefaultCredentials = preferences.GetBoolValue(WellKnownPreference.UseDefaultCredentials);\n            bool proxyUseDefaultCredentials = preferences.GetBoolValue(WellKnownPreference.ProxyUseDefaultCredentials);\n\n            if (useDefaultCredentials || proxyUseDefaultCredentials)\n            {\n#pragma warning disable CA2000 // Dispose objects before losing scope\n                HttpClientHandler handler = new HttpClientHandler()\n                {\n                    UseDefaultCredentials = useDefaultCredentials,\n                    DefaultProxyCredentials = proxyUseDefaultCredentials ? CredentialCache.DefaultCredentials : null\n                };\n\n                return new HttpClient(handler);\n#pragma warning restore CA2000 // Dispose objects before losing scope\n            }\n\n            return new HttpClient();\n        }\n\n        private static void RegisterEncodingProviders()\n        {\n            // Adds Windows-1252, among others\n            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Properties/AssemblyInfo.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.txt file in the project root for more information.\n\nusing System.Diagnostics.CodeAnalysis;\nusing System.Runtime.CompilerServices;\n\n[assembly: InternalsVisibleTo(\"Microsoft.HttpRepl.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9\")]\n[assembly: SuppressMessage(\"Design\", \"CA1031:Do not catch general exception types\", Justification = \"This is done commonly throughout the codebase to catch unexpected errors.\") ]\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Resources/Strings.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\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\nnamespace Microsoft.HttpRepl.Resources {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"17.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Strings {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Strings() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Microsoft.HttpRepl.Resources.Strings\", typeof(Strings).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Adds a key and value pair to the query string. The key and value will be UrlEncoded. Multiple values may be mapped to the same key..\n        /// </summary>\n        internal static string AddQueryParamCommand_HelpDetails {\n            get {\n                return ResourceManager.GetString(\"AddQueryParamCommand_HelpDetails\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Adds a key and value pair to the query string.\n        /// </summary>\n        internal static string AddQueryParamCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"AddQueryParamCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Cancelled.\n        /// </summary>\n        internal static string ApiConnection_Logging_Cancelled {\n            get {\n                return ResourceManager.GetString(\"ApiConnection_Logging_Cancelled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Checking {0}... .\n        /// </summary>\n        internal static string ApiConnection_Logging_Checking {\n            get {\n                return ResourceManager.GetString(\"ApiConnection_Logging_Checking\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Failed!.\n        /// </summary>\n        internal static string ApiConnection_Logging_Failed {\n            get {\n                return ResourceManager.GetString(\"ApiConnection_Logging_Failed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Found.\n        /// </summary>\n        internal static string ApiConnection_Logging_Found {\n            get {\n                return ResourceManager.GetString(\"ApiConnection_Logging_Found\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Parsing... .\n        /// </summary>\n        internal static string ApiConnection_Logging_Parsing {\n            get {\n                return ResourceManager.GetString(\"ApiConnection_Logging_Parsing\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Successful.\n        /// </summary>\n        internal static string ApiConnection_Logging_Successful {\n            get {\n                return ResourceManager.GetString(\"ApiConnection_Logging_Successful\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Successful (with warnings).\n        /// </summary>\n        internal static string ApiConnection_Logging_SuccessfulWithWarnings {\n            get {\n                return ResourceManager.GetString(\"ApiConnection_Logging_SuccessfulWithWarnings\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The specified content file, &quot;{0}&quot;, does not exist..\n        /// </summary>\n        internal static string BaseHttpCommand_Error_ContentFileDoesNotExist {\n            get {\n                return ResourceManager.GetString(\"BaseHttpCommand_Error_ContentFileDoesNotExist\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The specified default editor path, &quot;{0}&quot;, does not exist..\n        /// </summary>\n        internal static string BaseHttpCommand_Error_DefaultEditorDoesNotExist {\n            get {\n                return ResourceManager.GetString(\"BaseHttpCommand_Error_DefaultEditorDoesNotExist\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The default editor must be configured using the command `pref set {0} &quot;{{commandLine}}&quot;`..\n        /// </summary>\n        internal static string BaseHttpCommand_Error_DefaultEditorNotConfigured {\n            get {\n                return ResourceManager.GetString(\"BaseHttpCommand_Error_DefaultEditorNotConfigured\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Headers must be formatted as {header}={value} or {header}:{value}.\n        /// </summary>\n        internal static string BaseHttpCommand_Error_HeaderFormatting {\n            get {\n                return ResourceManager.GetString(\"BaseHttpCommand_Error_HeaderFormatting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The output files for the headers and the body must be two different files.\n        /// </summary>\n        internal static string BaseHttpCommand_Error_SameBodyAndHeaderFileName {\n            get {\n                return ResourceManager.GetString(\"BaseHttpCommand_Error_SameBodyAndHeaderFileName\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Streaming the response, press any key to stop....\n        /// </summary>\n        internal static string BaseHttpCommand_FormatBodyAsync_Streaming {\n            get {\n                return ResourceManager.GetString(\"BaseHttpCommand_FormatBodyAsync_Streaming\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Append the given directory to the currently selected path, or move up a path when using `cd ..`.\n        /// </summary>\n        internal static string ChangeDirectoryCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"ChangeDirectoryCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Warning: The &apos;{0}&apos; endpoint is not present in the OpenAPI description.\n        /// </summary>\n        internal static string ChangeDirectoryCommand_Warning_UnknownEndpoint {\n            get {\n                return ResourceManager.GetString(\"ChangeDirectoryCommand_Warning_UnknownEndpoint\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Removes all text from the shell.\n        /// </summary>\n        internal static string ClearCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"ClearCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clears the query string of all key and values.\n        /// </summary>\n        internal static string ClearQueryParamCommand_HelpDetails {\n            get {\n                return ResourceManager.GetString(\"ClearQueryParamCommand_HelpDetails\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clears the query string for all requests.\n        /// </summary>\n        internal static string ClearQueryParamCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"ClearQueryParamCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Configures the directory structure and base address of the api server.\n        /// </summary>\n        internal static string ConnectCommand_Description {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Description\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The base address must be a valid absolute url or relative url. If it is a relative url, the root address must be specified.\n        /// </summary>\n        internal static string ConnectCommand_Error_InvalidBase {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Error_InvalidBase\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The OpenAPI description address must be a valid absolute url or relative url. If it is a relative url, the root address must be specified.\n        /// </summary>\n        internal static string ConnectCommand_Error_InvalidSwagger {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Error_InvalidSwagger\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to If no root address is specified, the base address must be an absolute url, including scheme.\n        /// </summary>\n        internal static string ConnectCommand_Error_NoRootNoAbsoluteBase {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Error_NoRootNoAbsoluteBase\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to If no root address is specified, the OpenAPI description address must be an absolute url, including scheme.\n        /// </summary>\n        internal static string ConnectCommand_Error_NoRootNoAbsoluteSwagger {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Error_NoRootNoAbsoluteSwagger\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You must specify either a root address or a base address and an OpenAPI description address.\n        /// </summary>\n        internal static string ConnectCommand_Error_NothingSpecified {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Error_NothingSpecified\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to If specified, the root address must be a valid absolute url, including scheme.\n        /// </summary>\n        internal static string ConnectCommand_Error_RootAddressNotValid {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Error_RootAddressNotValid\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Configures the directory structure and base address of the api server based on the arguments and options specified. At least one of [rootAddress], [--base baseAddress] or [--openapi openApiDescriptionAddress] must be specified\n        ///\n        ///By default, existing headers set via the `set header` command and path segments beyond the base address are cleared when this command is executed. Use [--persist-headers] and [--persist-paths] to change those defaults.\n        /// </summary>\n        internal static string ConnectCommand_HelpDetails_Line1 {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_HelpDetails_Line1\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to [rootAddress] will be used to automatically determine the base address and OpenAPI description address.\n        /// </summary>\n        internal static string ConnectCommand_HelpDetails_Line2 {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_HelpDetails_Line2\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to [--base baseAddress] and [--openapi openApiDescriptionAddress] allow you to explicitly set those addresses and skip auto detection.\n        /// </summary>\n        internal static string ConnectCommand_HelpDetails_Line3 {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_HelpDetails_Line3\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to [--verbose] provides more detail about OpenAPI Description discovery and parsing.\n        /// </summary>\n        internal static string ConnectCommand_HelpDetails_Line4 {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_HelpDetails_Line4\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to [--persist-headers] leaves existing session headers in place when connecting to a new API.\n        /// </summary>\n        internal static string ConnectCommand_HelpDetails_Line5 {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_HelpDetails_Line5\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to [--persist-path] leaves existing path segments in place when connecting to a new API.\n        /// </summary>\n        internal static string ConnectCommand_HelpDetails_Line6 {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_HelpDetails_Line6\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Using a base address of {0}.\n        /// </summary>\n        internal static string ConnectCommand_Status_Base {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Status_Base\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to determine a base address.\n        /// </summary>\n        internal static string ConnectCommand_Status_NoBase {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Status_NoBase\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to find an OpenAPI description.\n        /// </summary>\n        internal static string ConnectCommand_Status_NoSwagger {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Status_NoSwagger\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Using OpenAPI description at {0}.\n        /// </summary>\n        internal static string ConnectCommand_Status_Swagger {\n            get {\n                return ResourceManager.GetString(\"ConnectCommand_Status_Swagger\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Allowed echo modes are &apos;on&apos; and &apos;off&apos;.\n        /// </summary>\n        internal static string EchoCommand_Error_AllowedModes {\n            get {\n                return ResourceManager.GetString(\"EchoCommand_Error_AllowedModes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Turns request echoing on or off, show the request that was made when using request commands.\n        /// </summary>\n        internal static string EchoCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"EchoCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The base address must be set before issuing requests to a relative path.\n        ///Use the `connect` command to set the base address and then try again.\n        ///Type `help connect` for more information on the `connect` command..\n        /// </summary>\n        internal static string Error_NoBasePath {\n            get {\n                return ResourceManager.GetString(\"Error_NoBasePath\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Cannot start the REPL when output is being redirected.\n        /// </summary>\n        internal static string Error_OutputRedirected {\n            get {\n                return ResourceManager.GetString(\"Error_OutputRedirected\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Exit the shell.\n        /// </summary>\n        internal static string ExitCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"ExitCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Arguments:.\n        /// </summary>\n        internal static string Help_Arguments {\n            get {\n                return ResourceManager.GetString(\"Help_Arguments\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to   {0} - The initial base address for the REPL..\n        /// </summary>\n        internal static string Help_BaseAddress {\n            get {\n                return ResourceManager.GetString(\"Help_BaseAddress\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to   {0} - Show help information..\n        /// </summary>\n        internal static string Help_Help {\n            get {\n                return ResourceManager.GetString(\"Help_Help\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Options:.\n        /// </summary>\n        internal static string Help_Options {\n            get {\n                return ResourceManager.GetString(\"Help_Options\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Once the REPL starts, these commands are valid:.\n        /// </summary>\n        internal static string Help_REPLCommands {\n            get {\n                return ResourceManager.GetString(\"Help_REPLCommands\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Usage: .\n        /// </summary>\n        internal static string Help_Usage {\n            get {\n                return ResourceManager.GetString(\"Help_Usage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to REPL Customization Commands:.\n        /// </summary>\n        internal static string HelpCommand_Core_CustomizationCommands {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_CustomizationCommands\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use these commands to customize the REPL behavior.\n        /// </summary>\n        internal static string HelpCommand_Core_CustomizationCommands_Description {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_CustomizationCommands_Description\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use `help &lt;COMMAND&gt;` for more detail on an individual command. e.g. `help get`.\n        /// </summary>\n        internal static string HelpCommand_Core_Details_Line1 {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_Details_Line1\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to For detailed tool info, see https://aka.ms/http-repl-doc.\n        /// </summary>\n        internal static string HelpCommand_Core_Details_Line2 {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_Details_Line2\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to HTTP Commands:.\n        /// </summary>\n        internal static string HelpCommand_Core_HttpCommands {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_HttpCommands\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use these commands to execute requests against your application.\n        /// </summary>\n        internal static string HelpCommand_Core_HttpCommands_Description {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_HttpCommands_Description\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Navigation Commands:.\n        /// </summary>\n        internal static string HelpCommand_Core_NavigationCommands {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_NavigationCommands\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The REPL allows you to navigate your URL space and focus on specific APIs that you are working on.\n        /// </summary>\n        internal static string HelpCommand_Core_NavigationCommands_Description {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_NavigationCommands_Description\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Setup Commands:.\n        /// </summary>\n        internal static string HelpCommand_Core_SetupCommands {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_SetupCommands\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use these commands to configure the tool for your API server.\n        /// </summary>\n        internal static string HelpCommand_Core_SetupCommands_Description {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_SetupCommands_Description\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Shell Commands:.\n        /// </summary>\n        internal static string HelpCommand_Core_ShellCommands {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_ShellCommands\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use these commands to interact with the REPL shell.\n        /// </summary>\n        internal static string HelpCommand_Core_ShellCommands_Description {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Core_ShellCommands_Description\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to locate any help information for the specified command.\n        /// </summary>\n        internal static string HelpCommand_Error_UnableToLocateHelpInfo {\n            get {\n                return ResourceManager.GetString(\"HelpCommand_Error_UnableToLocateHelpInfo\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to If {0} is not an absolute URI, {1} must be specified..\n        /// </summary>\n        internal static string HttpState_Error_NoAbsoluteUriNoBaseAddress {\n            get {\n                return ResourceManager.GetString(\"HttpState_Error_NoAbsoluteUriNoBaseAddress\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Accepts:.\n        /// </summary>\n        internal static string ListCommand_Accepts {\n            get {\n                return ResourceManager.GetString(\"ListCommand_Accepts\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Available methods:.\n        /// </summary>\n        internal static string ListCommand_AvailableMethods {\n            get {\n                return ResourceManager.GetString(\"ListCommand_AvailableMethods\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to No base address has been set, so there is nothing to list.\n        ///Use the `connect` command to set the base address and then try again.\n        ///Type `help connect` for more information on the `connect` command..\n        /// </summary>\n        internal static string ListCommand_Error_NoBaseAddress {\n            get {\n                return ResourceManager.GetString(\"ListCommand_Error_NoBaseAddress\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to No directory structure has been set, so there is nothing to list. Use the &quot;connect&quot; command to set a directory structure based on an OpenAPI description..\n        /// </summary>\n        internal static string ListCommand_Error_NoDirectoryStructure {\n            get {\n                return ResourceManager.GetString(\"ListCommand_Error_NoDirectoryStructure\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show all endpoints for the current path.\n        /// </summary>\n        internal static string ListCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"ListCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Options:.\n        /// </summary>\n        internal static string Options {\n            get {\n                return ResourceManager.GetString(\"Options\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to {0} does not have a configured value.\n        /// </summary>\n        internal static string PrefCommand_Error_NoConfiguredValue {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_Error_NoConfiguredValue\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Whether to get or set a preference must be specified.\n        /// </summary>\n        internal static string PrefCommand_Error_NoGetOrSet {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_Error_NoGetOrSet\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The preference to set must be specified.\n        /// </summary>\n        internal static string PrefCommand_Error_NoPreferenceName {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_Error_NoPreferenceName\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Error saving preferences.\n        /// </summary>\n        internal static string PrefCommand_Error_Saving {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_Error_Saving\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Configured value: {0}.\n        /// </summary>\n        internal static string PrefCommand_Get_ConfiguredValue {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_Get_ConfiguredValue\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Current Preferences:.\n        /// </summary>\n        internal static string PrefCommand_HelpDetails_CurrentPreferences {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_HelpDetails_CurrentPreferences\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Current Default Preferences:.\n        /// </summary>\n        internal static string PrefCommand_HelpDetails_DefaultPreferences {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_HelpDetails_DefaultPreferences\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to {0} - Gets the value of the specified preference or lists all preferences if no preference is specified.\n        /// </summary>\n        internal static string PrefCommand_HelpDetails_GetSyntax {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_HelpDetails_GetSyntax\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to {0} - Sets (or clears if value is not specified) the value of the specified preference.\n        /// </summary>\n        internal static string PrefCommand_HelpDetails_SetSyntax {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_HelpDetails_SetSyntax\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to {0} - Get or sets a preference to a particular value.\n        /// </summary>\n        internal static string PrefCommand_HelpDetails_Syntax {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_HelpDetails_Syntax\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Allows viewing or changing preferences, e.g. &apos;pref set editor.command.default &apos;C:\\\\Program Files\\\\Microsoft VS Code\\\\Code.exe&apos;`.\n        /// </summary>\n        internal static string PrefCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to If your default editor is Visual Studio Code, you should set the default command arguments (`{0}`) to include `-w` or `--wait` to ensure proper integration between HttpRepl and Visual Studio Code..\n        /// </summary>\n        internal static string PrefCommand_Set_VSCode {\n            get {\n                return ResourceManager.GetString(\"PrefCommand_Set_VSCode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to If specified, {0} must begin with a period and have at least one character after the period..\n        /// </summary>\n        internal static string RealFileSystem_Error_InvalidExtension {\n            get {\n                return ResourceManager.GetString(\"RealFileSystem_Error_InvalidExtension\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Could not find script file {0}.\n        /// </summary>\n        internal static string RunCommand_CouldNotFindScriptFile {\n            get {\n                return ResourceManager.GetString(\"RunCommand_CouldNotFindScriptFile\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to run {path to script}\n        ///\n        ///Runs the specified script.\n        ///A script is a text file containing one CLI command per line. Each line will be run as if it was typed into the CLI.\n        ///\n        ///When +history option is specified, commands specified in the text file will be added to command history..\n        /// </summary>\n        internal static string RunCommand_HelpDetails {\n            get {\n                return ResourceManager.GetString(\"RunCommand_HelpDetails\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Runs the script at the given path. A script is a set of commands that can be typed with one command per line.\n        /// </summary>\n        internal static string RunCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"RunCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sets or clears a header. When [value] is empty the header is cleared..\n        /// </summary>\n        internal static string SetHeaderCommand_HelpDetails {\n            get {\n                return ResourceManager.GetString(\"SetHeaderCommand_HelpDetails\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sets or clears a header for all requests. e.g. `set header content-type application/json`.\n        /// </summary>\n        internal static string SetHeaderCommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"SetHeaderCommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Welcome to HttpRepl {0}!\n        ///------------------------\n        ///\n        ///Telemetry\n        ///---------\n        ///The .NET tools collect usage data in order to help us improve your experience. The data is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_HTTPREPL_TELEMETRY_OPTOUT environment variable to &apos;1&apos; or &apos;true&apos; using your favorite shell.\n        ///\n        ///Read more about HttpRepl telemetry: https://aka.ms/httprepl-telemetry\n        ///Read more about .NET CLI Tools telemetry: https://aka.ms/dotnet-cli-telemet [rest of string was truncated]&quot;;.\n        /// </summary>\n        internal static string Telemetry_WelcomeMessage {\n            get {\n                return ResourceManager.GetString(\"Telemetry_WelcomeMessage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Launches the Swagger UI page (if available) in the default browser.\n        /// </summary>\n        internal static string UICommand_Description {\n            get {\n                return ResourceManager.GetString(\"UICommand_Description\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Displays the Swagger UI page, if available, in the default browser.\n        /// </summary>\n        internal static string UICommand_HelpSummary {\n            get {\n                return ResourceManager.GetString(\"UICommand_HelpSummary\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The {0} command uses multiple sources to determine the Swagger UI endpoint. In order of precedence:.\n        /// </summary>\n        internal static string UICommand_HelpText_Line1 {\n            get {\n                return ResourceManager.GetString(\"UICommand_HelpText_Line1\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to   1. The {0} parameter, if specified.\n        /// </summary>\n        internal static string UICommand_HelpText_Line2 {\n            get {\n                return ResourceManager.GetString(\"UICommand_HelpText_Line2\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to   2. The {0} preference, if set.\n        /// </summary>\n        internal static string UICommand_HelpText_Line3 {\n            get {\n                return ResourceManager.GetString(\"UICommand_HelpText_Line3\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to   3. A default URL of {0}.\n        /// </summary>\n        internal static string UICommand_HelpText_Line4 {\n            get {\n                return ResourceManager.GetString(\"UICommand_HelpText_Line4\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The parameter &apos;{0}&apos; could not be converted into a valid uri..\n        /// </summary>\n        internal static string UICommand_InvalidParameter {\n            get {\n                return ResourceManager.GetString(\"UICommand_InvalidParameter\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Must be connected to a server to launch Swagger UI.\n        /// </summary>\n        internal static string UICommand_NotConnectedToServerError {\n            get {\n                return ResourceManager.GetString(\"UICommand_NotConnectedToServerError\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to launch {0}.\n        /// </summary>\n        internal static string UICommand_UnableToLaunchUriError {\n            get {\n                return ResourceManager.GetString(\"UICommand_UnableToLaunchUriError\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Usage: .\n        /// </summary>\n        internal static string Usage {\n            get {\n                return ResourceManager.GetString(\"Usage\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Resources/Strings.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"ChangeDirectoryCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Append the given directory to the currently selected path, or move up a path when using `cd ..`</value>\n  </data>\n  <data name=\"ChangeDirectoryCommand_Warning_UnknownEndpoint\" xml:space=\"preserve\">\n    <value>Warning: The '{0}' endpoint is not present in the OpenAPI description</value>\n    <comment>{0} is the path to the referenced endpoint</comment>\n  </data>\n  <data name=\"ClearCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Removes all text from the shell</value>\n  </data>\n  <data name=\"EchoCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Turns request echoing on or off, show the request that was made when using request commands</value>\n  </data>\n  <data name=\"Error_NoBasePath\" xml:space=\"preserve\">\n    <value>The base address must be set before issuing requests to a relative path.\nUse the `connect` command to set the base address and then try again.\nType `help connect` for more information on the `connect` command.</value>\n    <comment>Error shown in console when issuing an HTTP command without first setting the base url</comment>\n  </data>\n  <data name=\"Error_OutputRedirected\" xml:space=\"preserve\">\n    <value>Cannot start the REPL when output is being redirected</value>\n  </data>\n  <data name=\"ExitCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Exit the shell</value>\n  </data>\n  <data name=\"Help_Arguments\" xml:space=\"preserve\">\n    <value>Arguments:</value>\n  </data>\n  <data name=\"Help_BaseAddress\" xml:space=\"preserve\">\n    <value>  {0} - The initial base address for the REPL.</value>\n    <comment>{0} is the &lt;BASE_ADDRESS&gt; syntax specifier</comment>\n  </data>\n  <data name=\"Help_Help\" xml:space=\"preserve\">\n    <value>  {0} - Show help information.</value>\n    <comment>{0} is the --help syntax specifier</comment>\n  </data>\n  <data name=\"Help_Options\" xml:space=\"preserve\">\n    <value>Options:</value>\n  </data>\n  <data name=\"Help_REPLCommands\" xml:space=\"preserve\">\n    <value>Once the REPL starts, these commands are valid:</value>\n  </data>\n  <data name=\"Help_Usage\" xml:space=\"preserve\">\n    <value>Usage: </value>\n  </data>\n  <data name=\"ListCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Show all endpoints for the current path</value>\n  </data>\n  <data name=\"PrefCommand_Error_NoConfiguredValue\" xml:space=\"preserve\">\n    <value>{0} does not have a configured value</value>\n    <comment>{0} is the name of the requested preference</comment>\n  </data>\n  <data name=\"PrefCommand_Error_NoGetOrSet\" xml:space=\"preserve\">\n    <value>Whether to get or set a preference must be specified</value>\n  </data>\n  <data name=\"PrefCommand_Error_NoPreferenceName\" xml:space=\"preserve\">\n    <value>The preference to set must be specified</value>\n  </data>\n  <data name=\"PrefCommand_Error_Saving\" xml:space=\"preserve\">\n    <value>Error saving preferences</value>\n  </data>\n  <data name=\"PrefCommand_Get_ConfiguredValue\" xml:space=\"preserve\">\n    <value>Configured value: {0}</value>\n    <comment>{0} is the value of the specified preference</comment>\n  </data>\n  <data name=\"PrefCommand_HelpDetails_CurrentPreferences\" xml:space=\"preserve\">\n    <value>Current Preferences:</value>\n  </data>\n  <data name=\"PrefCommand_HelpDetails_DefaultPreferences\" xml:space=\"preserve\">\n    <value>Current Default Preferences:</value>\n  </data>\n  <data name=\"PrefCommand_HelpDetails_GetSyntax\" xml:space=\"preserve\">\n    <value>{0} - Gets the value of the specified preference or lists all preferences if no preference is specified</value>\n    <comment>{0} is the get command syntax</comment>\n  </data>\n  <data name=\"PrefCommand_HelpDetails_SetSyntax\" xml:space=\"preserve\">\n    <value>{0} - Sets (or clears if value is not specified) the value of the specified preference</value>\n    <comment>{0} is the set command syntax</comment>\n  </data>\n  <data name=\"PrefCommand_HelpDetails_Syntax\" xml:space=\"preserve\">\n    <value>{0} - Get or sets a preference to a particular value</value>\n    <comment>{0} is the overall command syntax</comment>\n  </data>\n  <data name=\"PrefCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Allows viewing or changing preferences, e.g. 'pref set editor.command.default 'C:\\\\Program Files\\\\Microsoft VS Code\\\\Code.exe'`</value>\n  </data>\n  <data name=\"RunCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Runs the script at the given path. A script is a set of commands that can be typed with one command per line</value>\n  </data>\n  <data name=\"SetHeaderCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Sets or clears a header for all requests. e.g. `set header content-type application/json`</value>\n  </data>\n  <data name=\"AddQueryParamCommand_HelpDetails\" xml:space=\"preserve\">\n    <value>Adds a key and value pair to the query string. The key and value will be UrlEncoded. Multiple values may be mapped to the same key.</value>\n  </data>\n  <data name=\"UICommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Displays the Swagger UI page, if available, in the default browser</value>\n  </data>\n  <data name=\"UICommand_Description\" xml:space=\"preserve\">\n    <value>Launches the Swagger UI page (if available) in the default browser</value>\n  </data>\n  <data name=\"UICommand_NotConnectedToServerError\" xml:space=\"preserve\">\n    <value>Must be connected to a server to launch Swagger UI</value>\n  </data>\n  <data name=\"UICommand_UnableToLaunchUriError\" xml:space=\"preserve\">\n    <value>Unable to launch {0}</value>\n    <comment>{0} indicates a uri</comment>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>Usage: </value>\n  </data>\n  <data name=\"SetHeaderCommand_HelpDetails\" xml:space=\"preserve\">\n    <value>Sets or clears a header. When [value] is empty the header is cleared.</value>\n  </data>\n  <data name=\"RunCommand_HelpDetails\" xml:space=\"preserve\">\n    <value>run {path to script}\n\nRuns the specified script.\nA script is a text file containing one CLI command per line. Each line will be run as if it was typed into the CLI.\n\nWhen +history option is specified, commands specified in the text file will be added to command history.</value>\n  </data>\n  <data name=\"RunCommand_CouldNotFindScriptFile\" xml:space=\"preserve\">\n    <value>Could not find script file {0}</value>\n    <comment>{0} indicates path to provided script file</comment>\n  </data>\n  <data name=\"HttpState_Error_NoAbsoluteUriNoBaseAddress\" xml:space=\"preserve\">\n    <value>If {0} is not an absolute URI, {1} must be specified.</value>\n    <comment>{0} is the name of the commandSpecifiedPath parameter, {1} is the name of the baseAddress uri parameter</comment>\n  </data>\n  <data name=\"ListCommand_Error_NoBaseAddress\" xml:space=\"preserve\">\n    <value>No base address has been set, so there is nothing to list.\nUse the `connect` command to set the base address and then try again.\nType `help connect` for more information on the `connect` command.</value>\n  </data>\n  <data name=\"ListCommand_Error_NoDirectoryStructure\" xml:space=\"preserve\">\n    <value>No directory structure has been set, so there is nothing to list. Use the \"connect\" command to set a directory structure based on an OpenAPI description.</value>\n  </data>\n  <data name=\"ConnectCommand_Error_InvalidBase\" xml:space=\"preserve\">\n    <value>The base address must be a valid absolute url or relative url. If it is a relative url, the root address must be specified</value>\n  </data>\n  <data name=\"ConnectCommand_Error_InvalidSwagger\" xml:space=\"preserve\">\n    <value>The OpenAPI description address must be a valid absolute url or relative url. If it is a relative url, the root address must be specified</value>\n  </data>\n  <data name=\"ConnectCommand_Error_NoRootNoAbsoluteBase\" xml:space=\"preserve\">\n    <value>If no root address is specified, the base address must be an absolute url, including scheme</value>\n  </data>\n  <data name=\"ConnectCommand_Error_NoRootNoAbsoluteSwagger\" xml:space=\"preserve\">\n    <value>If no root address is specified, the OpenAPI description address must be an absolute url, including scheme</value>\n  </data>\n  <data name=\"ConnectCommand_Error_NothingSpecified\" xml:space=\"preserve\">\n    <value>You must specify either a root address or a base address and an OpenAPI description address</value>\n  </data>\n  <data name=\"ConnectCommand_Error_RootAddressNotValid\" xml:space=\"preserve\">\n    <value>If specified, the root address must be a valid absolute url, including scheme</value>\n  </data>\n  <data name=\"ConnectCommand_Status_Base\" xml:space=\"preserve\">\n    <value>Using a base address of {0}</value>\n    <comment>{0} indicates a uri</comment>\n  </data>\n  <data name=\"ConnectCommand_Status_NoBase\" xml:space=\"preserve\">\n    <value>Unable to determine a base address</value>\n  </data>\n  <data name=\"ConnectCommand_Status_Swagger\" xml:space=\"preserve\">\n    <value>Using OpenAPI description at {0}</value>\n    <comment>{0} indicates a uri</comment>\n  </data>\n  <data name=\"ConnectCommand_Status_NoSwagger\" xml:space=\"preserve\">\n    <value>Unable to find an OpenAPI description</value>\n  </data>\n  <data name=\"ConnectCommand_Description\" xml:space=\"preserve\">\n    <value>Configures the directory structure and base address of the api server</value>\n  </data>\n  <data name=\"ConnectCommand_HelpDetails_Line1\" xml:space=\"preserve\">\n    <value>Configures the directory structure and base address of the api server based on the arguments and options specified. At least one of [rootAddress], [--base baseAddress] or [--openapi openApiDescriptionAddress] must be specified\n\nBy default, existing headers set via the `set header` command and path segments beyond the base address are cleared when this command is executed. Use [--persist-headers] and [--persist-paths] to change those defaults</value>\n  </data>\n  <data name=\"ConnectCommand_HelpDetails_Line2\" xml:space=\"preserve\">\n    <value>[rootAddress] will be used to automatically determine the base address and OpenAPI description address</value>\n  </data>\n  <data name=\"ConnectCommand_HelpDetails_Line3\" xml:space=\"preserve\">\n    <value>[--base baseAddress] and [--openapi openApiDescriptionAddress] allow you to explicitly set those addresses and skip auto detection</value>\n  </data>\n  <data name=\"HelpCommand_Core_CustomizationCommands\" xml:space=\"preserve\">\n    <value>REPL Customization Commands:</value>\n  </data>\n  <data name=\"HelpCommand_Core_CustomizationCommands_Description\" xml:space=\"preserve\">\n    <value>Use these commands to customize the REPL behavior</value>\n  </data>\n  <data name=\"HelpCommand_Core_Details_Line1\" xml:space=\"preserve\">\n    <value>Use `help &lt;COMMAND&gt;` for more detail on an individual command. e.g. `help get`</value>\n  </data>\n  <data name=\"HelpCommand_Core_Details_Line2\" xml:space=\"preserve\">\n    <value>For detailed tool info, see https://aka.ms/http-repl-doc</value>\n  </data>\n  <data name=\"HelpCommand_Core_HttpCommands\" xml:space=\"preserve\">\n    <value>HTTP Commands:</value>\n  </data>\n  <data name=\"HelpCommand_Core_HttpCommands_Description\" xml:space=\"preserve\">\n    <value>Use these commands to execute requests against your application</value>\n  </data>\n  <data name=\"HelpCommand_Core_NavigationCommands\" xml:space=\"preserve\">\n    <value>Navigation Commands:</value>\n  </data>\n  <data name=\"HelpCommand_Core_NavigationCommands_Description\" xml:space=\"preserve\">\n    <value>The REPL allows you to navigate your URL space and focus on specific APIs that you are working on</value>\n  </data>\n  <data name=\"HelpCommand_Core_SetupCommands\" xml:space=\"preserve\">\n    <value>Setup Commands:</value>\n  </data>\n  <data name=\"HelpCommand_Core_SetupCommands_Description\" xml:space=\"preserve\">\n    <value>Use these commands to configure the tool for your API server</value>\n  </data>\n  <data name=\"HelpCommand_Core_ShellCommands\" xml:space=\"preserve\">\n    <value>Shell Commands:</value>\n  </data>\n  <data name=\"HelpCommand_Core_ShellCommands_Description\" xml:space=\"preserve\">\n    <value>Use these commands to interact with the REPL shell</value>\n  </data>\n  <data name=\"RealFileSystem_Error_InvalidExtension\" xml:space=\"preserve\">\n    <value>If specified, {0} must begin with a period and have at least one character after the period.</value>\n    <comment>{0} is the parameter name</comment>\n  </data>\n  <data name=\"UICommand_InvalidParameter\" xml:space=\"preserve\">\n    <value>The parameter '{0}' could not be converted into a valid uri.</value>\n    <comment>{0} is a string parameter to the UI command</comment>\n  </data>\n  <data name=\"UICommand_HelpText_Line1\" xml:space=\"preserve\">\n    <value>The {0} command uses multiple sources to determine the Swagger UI endpoint. In order of precedence:</value>\n    <comment>{0} is the name of the ui command (ui)</comment>\n  </data>\n  <data name=\"UICommand_HelpText_Line2\" xml:space=\"preserve\">\n    <value>  1. The {0} parameter, if specified</value>\n    <comment>{0} is the syntax for the parameter, e.g. {swaggerUIAddress}</comment>\n  </data>\n  <data name=\"UICommand_HelpText_Line3\" xml:space=\"preserve\">\n    <value>  2. The {0} preference, if set</value>\n    <comment>{0} is the name of the preference, e.g. swagger.uiEndpoint</comment>\n  </data>\n  <data name=\"UICommand_HelpText_Line4\" xml:space=\"preserve\">\n    <value>  3. A default URL of {0}</value>\n    <comment>{0} is the default address, e.g. [BaseAddress]/swagger</comment>\n  </data>\n  <data name=\"BaseHttpCommand_Error_HeaderFormatting\" xml:space=\"preserve\">\n    <value>Headers must be formatted as {header}={value} or {header}:{value}</value>\n  </data>\n  <data name=\"BaseHttpCommand_FormatBodyAsync_Streaming\" xml:space=\"preserve\">\n    <value>Streaming the response, press any key to stop...</value>\n  </data>\n  <data name=\"EchoCommand_Error_AllowedModes\" xml:space=\"preserve\">\n    <value>Allowed echo modes are 'on' and 'off'</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>Options:</value>\n  </data>\n  <data name=\"BaseHttpCommand_Error_ContentFileDoesNotExist\" xml:space=\"preserve\">\n    <value>The specified content file, \"{0}\", does not exist.</value>\n    <comment>{0} is the user supplied content file path</comment>\n  </data>\n  <data name=\"BaseHttpCommand_Error_DefaultEditorDoesNotExist\" xml:space=\"preserve\">\n    <value>The specified default editor path, \"{0}\", does not exist.</value>\n    <comment>{0} is the user supplied default editor preference value</comment>\n  </data>\n  <data name=\"BaseHttpCommand_Error_DefaultEditorNotConfigured\" xml:space=\"preserve\">\n    <value>The default editor must be configured using the command `pref set {0} \"{{commandLine}}\"`.</value>\n    <comment>{0} is the name of the default editor preference</comment>\n  </data>\n  <data name=\"Telemetry_WelcomeMessage\" xml:space=\"preserve\">\n    <value>Welcome to HttpRepl {0}!\n------------------------\n\nTelemetry\n---------\nThe .NET tools collect usage data in order to help us improve your experience. The data is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_HTTPREPL_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell.\n\nRead more about HttpRepl telemetry: https://aka.ms/httprepl-telemetry\nRead more about .NET CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry\n</value>\n    <comment>{0} is the major.minor version of the current build</comment>\n  </data>\n  <data name=\"ListCommand_Accepts\" xml:space=\"preserve\">\n    <value>Accepts:</value>\n  </data>\n  <data name=\"ListCommand_AvailableMethods\" xml:space=\"preserve\">\n    <value>Available methods:</value>\n  </data>\n  <data name=\"PrefCommand_Set_VSCode\" xml:space=\"preserve\">\n    <value>If your default editor is Visual Studio Code, you should set the default command arguments (`{0}`) to include `-w` or `--wait` to ensure proper integration between HttpRepl and Visual Studio Code.</value>\n    <comment>{0} indicates the preference name for the default editor arguments</comment>\n  </data>\n  <data name=\"HelpCommand_Error_UnableToLocateHelpInfo\" xml:space=\"preserve\">\n    <value>Unable to locate any help information for the specified command</value>\n  </data>\n  <data name=\"ConnectCommand_HelpDetails_Line4\" xml:space=\"preserve\">\n    <value>[--verbose] provides more detail about OpenAPI Description discovery and parsing</value>\n  </data>\n  <data name=\"ApiConnection_Logging_Cancelled\" xml:space=\"preserve\">\n    <value>Cancelled</value>\n  </data>\n  <data name=\"ApiConnection_Logging_Checking\" xml:space=\"preserve\">\n    <value>Checking {0}... </value>\n    <comment>{0} indicates a uri</comment>\n  </data>\n  <data name=\"ApiConnection_Logging_Failed\" xml:space=\"preserve\">\n    <value>Failed!</value>\n  </data>\n  <data name=\"ApiConnection_Logging_Found\" xml:space=\"preserve\">\n    <value>Found</value>\n  </data>\n  <data name=\"ApiConnection_Logging_Parsing\" xml:space=\"preserve\">\n    <value>Parsing... </value>\n  </data>\n  <data name=\"ApiConnection_Logging_Successful\" xml:space=\"preserve\">\n    <value>Successful</value>\n  </data>\n  <data name=\"BaseHttpCommand_Error_SameBodyAndHeaderFileName\" xml:space=\"preserve\">\n    <value>The output files for the headers and the body must be two different files</value>\n  </data>\n  <data name=\"ApiConnection_Logging_SuccessfulWithWarnings\" xml:space=\"preserve\">\n    <value>Successful (with warnings)</value>\n  </data>\n  <data name=\"ConnectCommand_HelpDetails_Line5\" xml:space=\"preserve\">\n    <value>[--persist-headers] leaves existing session headers in place when connecting to a new API</value>\n  </data>\n  <data name=\"ConnectCommand_HelpDetails_Line6\" xml:space=\"preserve\">\n    <value>[--persist-path] leaves existing path segments in place when connecting to a new API</value>\n  </data>\n  <data name=\"AddQueryParamCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Adds a key and value pair to the query string</value>\n  </data>\n  <data name=\"ClearQueryParamCommand_HelpDetails\" xml:space=\"preserve\">\n    <value>Clears the query string of all key and values</value>\n  </data>\n  <data name=\"ClearQueryParamCommand_HelpSummary\" xml:space=\"preserve\">\n    <value>Clears the query string for all requests</value>\n  </data>\n</root>"
  },
  {
    "path": "src/Microsoft.HttpRepl/Suggestions/HeaderCompletion.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Microsoft.HttpRepl.Suggestions\n{\n    public static class HeaderCompletion\n    {\n        /// <summary>\n        /// Gets a collection of HTTP header names which starts with the prefix value passed in, except the ones present in existingHeaders.\n        /// </summary>\n        /// <param name=\"existingHeaders\">A collection of existing headers.</param>\n        /// <param name=\"prefix\">The prefix value to get completion suggestion items for.</param>\n        /// <returns></returns>\n        public static IEnumerable<string> GetCompletions(IReadOnlyCollection<string> existingHeaders, string prefix)\n        {\n            return WellKnownHeaders.CommonHeaders.Where(x => x.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) &&\n                                                             existingHeaders?.Contains(x) != true);\n        }\n\n        public static IEnumerable<string> GetValueCompletions(string method, string path, string header, string prefix, HttpState programState)\n        {\n            header = header ?? throw new ArgumentNullException(nameof(header));\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            switch (header.ToUpperInvariant())\n            {\n                case \"CONTENT-TYPE\":\n                    IEnumerable<string> results = programState.GetApplicableContentTypes(method, path);\n\n                    return results?.Where(x => !string.IsNullOrEmpty(x) && x.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));\n                default:\n                    return null;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Suggestions/ServerPathCompletion.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Microsoft.HttpRepl.Suggestions\n{\n    public static class ServerPathCompletion\n    {\n        public static IEnumerable<string> GetCompletions(HttpState programState, string normalCompletionString)\n        {\n            //If it's an absolute URI, nothing to suggest\n            if (Uri.IsWellFormedUriString(normalCompletionString, UriKind.Absolute))\n            {\n                return null;\n            }\n\n            programState = programState ?? throw new ArgumentNullException(nameof(programState));\n\n            normalCompletionString = normalCompletionString ?? throw new ArgumentNullException(nameof(normalCompletionString));\n\n            if (programState.Structure is null)\n            {\n                return null;\n            }\n\n            string path = normalCompletionString.Replace('\\\\', '/');\n            int searchFrom = normalCompletionString.Length - 1;\n            int lastSlash = path.LastIndexOf('/', searchFrom);\n            string prefix;\n\n            if (lastSlash < 0)\n            {\n                path = string.Empty;\n                prefix = normalCompletionString;\n            }\n            else\n            {\n                path = path.Substring(0, lastSlash + 1);\n                prefix = normalCompletionString.Substring(lastSlash + 1);\n            }\n\n            IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);\n\n            if (s?.DirectoryNames == null)\n            {\n                return null;\n            }\n\n            List<string> results = new List<string>();\n\n            foreach (string child in s.DirectoryNames)\n            {\n                if (child.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))\n                {\n                    results.Add(path + child);\n                }\n            }\n\n            return results;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/DefaultCommandDispatcherExtensions.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal static class DefaultCommandDispatcherExtensions\n    {\n        public static void AddCommandWithTelemetry(this DefaultCommandDispatcher<HttpState, ICoreParseResult> defaultCommandDispatcher,\n                                                   ITelemetry telemetry,\n                                                   ICommand<HttpState, ICoreParseResult> command)\n        {\n            defaultCommandDispatcher.AddCommand(new TelemetryCommandWrapper(telemetry, command));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/AddQueryParamEvent.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.txt file in the project root for more information.\n\nnamespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal class AddQueryParamEvent : TelemetryEventBase\n    {\n        public AddQueryParamEvent(string key, bool isValueEmpty) : base(TelemetryEventNames.AddQueryParam)\n        {\n            SetProperty(TelemetryPropertyNames.AddQueryParam_Key, SanitizeKey(key));\n            SetProperty(TelemetryPropertyNames.AddQueryParam_IsValueEmpty, isValueEmpty);\n        }\n\n        private static string SanitizeKey(string headerName)\n        {\n            if (string.IsNullOrEmpty(headerName))\n            {\n                return headerName;\n            }\n\n            return Sha256Hasher.Hash(headerName);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/ClearQueryParamEvent.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.txt file in the project root for more information.\n\nnamespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal class ClearQueryParamEvent: TelemetryEventBase\n    {\n        public ClearQueryParamEvent(string key, bool isValueEmpty) : base(TelemetryEventNames.ClearQueryParam)\n        {\n            SetProperty(TelemetryPropertyNames.ClearQueryParam_Key, SanitizeKey(key));\n            SetProperty(TelemetryPropertyNames.ClearQueryParam_IsValueEmpty, isValueEmpty);\n        }\n\n        private static string SanitizeKey(string headerName)\n        {\n            if (string.IsNullOrEmpty(headerName))\n            {\n                return headerName;\n            }\n\n            return Sha256Hasher.Hash(headerName);\n        }\n    }\n}\n\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/CommandExecutedEvent.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.txt file in the project root for more information.\n\nnamespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal class CommandExecutedEvent : TelemetryEventBase\n    {\n        public CommandExecutedEvent(string commandName, bool wasSuccessful) : base(TelemetryEventNames.CommandExecuted)\n        {\n            SetProperty(TelemetryPropertyNames.CommandExecuted_CommandName, commandName);\n            SetProperty(TelemetryPropertyNames.CommandExecuted_WasSuccessful, wasSuccessful);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/ConnectEvent.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.txt file in the project root for more information.\n\nnamespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal class ConnectEvent : TelemetryEventBase\n    {\n        public ConnectEvent(bool baseSpecified, bool rootSpecified, bool openApiSpecified, bool openApiFound) : base(TelemetryEventNames.Connect)\n        {\n            SetProperty(TelemetryPropertyNames.Connect_BaseSpecified, baseSpecified);\n            SetProperty(TelemetryPropertyNames.Connect_RootSpecified, rootSpecified);\n            SetProperty(TelemetryPropertyNames.Connect_OpenApiSpecified, openApiSpecified);\n            SetProperty(TelemetryPropertyNames.Connect_OpenApiFound, openApiFound);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/HttpCommandEvent.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.txt file in the project root for more information.\n\nnamespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal class HttpCommandEvent : TelemetryEventBase\n    {\n        public HttpCommandEvent(string method, bool isPathSpecified, bool isHeaderSpecified, bool isResponseHeadersFileSpecified,\n                                bool isResponseBodyFileSpecified, bool isNoFormattingSpecified, bool isStreamingSpecified,\n                                bool isNoBodySpecified, bool isRequestBodyFileSpecified, bool isRequestBodyContentSpecified)\n            : base(TelemetryEventNames.HttpCommand)\n        {\n            SetProperty(TelemetryPropertyNames.HttpCommand_Method, method);\n            SetProperty(TelemetryPropertyNames.HttpCommand_PathSpecified, isPathSpecified);\n            SetProperty(TelemetryPropertyNames.HttpCommand_HeaderSpecified, isHeaderSpecified);\n            SetProperty(TelemetryPropertyNames.HttpCommand_ResponseHeadersFileSpecified, isResponseHeadersFileSpecified);\n            SetProperty(TelemetryPropertyNames.HttpCommand_ResponseBodyFileSpecified, isResponseBodyFileSpecified);\n            SetProperty(TelemetryPropertyNames.HttpCommand_NoFormattingSpecified, isNoFormattingSpecified);\n            SetProperty(TelemetryPropertyNames.HttpCommand_StreamingSpecified, isStreamingSpecified);\n            SetProperty(TelemetryPropertyNames.HttpCommand_NoBodySpecified, isNoBodySpecified);\n            SetProperty(TelemetryPropertyNames.HttpCommand_RequestBodyFileSpecified, isRequestBodyFileSpecified);\n            SetProperty(TelemetryPropertyNames.HttpCommand_RequestBodyContentSpecified, isRequestBodyContentSpecified);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/PreferenceEvent.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.txt file in the project root for more information.\n\nusing System;\nusing System.Linq;\nusing Microsoft.HttpRepl.Preferences;\n\nnamespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal class PreferenceEvent : TelemetryEventBase\n    {\n        public PreferenceEvent(string getOrSet, string preferenceName) : base(TelemetryEventNames.Preference)\n        {\n            SetProperty(TelemetryPropertyNames.Preference_GetOrSet, getOrSet);\n            SetProperty(TelemetryPropertyNames.Preference_PreferenceName, SanitizePreferenceName(preferenceName));\n        }\n\n        private static string SanitizePreferenceName(string preferenceName)\n        {\n            if (string.IsNullOrEmpty(preferenceName) ||\n                WellKnownPreference.Catalog.Names.Contains(preferenceName, StringComparer.OrdinalIgnoreCase))\n            {\n                return preferenceName;\n            }\n\n            return Sha256Hasher.Hash(preferenceName);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/SetHeaderEvent.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.txt file in the project root for more information.\n\nusing System;\nusing System.Linq;\n\nnamespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal class SetHeaderEvent : TelemetryEventBase\n    {\n        public SetHeaderEvent(string headerName, bool isValueEmpty) : base(TelemetryEventNames.SetHeader)\n        {\n            SetProperty(TelemetryPropertyNames.SetHeader_HeaderName, SanitizeHeaderName(headerName));\n            SetProperty(TelemetryPropertyNames.SetHeader_IsValueEmpty, isValueEmpty);\n        }\n\n        private static string SanitizeHeaderName(string headerName)\n        {\n            if (string.IsNullOrEmpty(headerName) ||\n                WellKnownHeaders.CommonHeaders.Contains(headerName, StringComparer.OrdinalIgnoreCase))\n            {\n                return headerName;\n            }\n\n            return Sha256Hasher.Hash(headerName);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/StartedEvent.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.txt file in the project root for more information.\n\nnamespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal class StartedEvent : TelemetryEventBase\n    {\n        public StartedEvent(bool withHelp, bool withRun, bool withOtherArgs, bool withOutputRedirection) : base(TelemetryEventNames.Started)\n        {\n            SetProperty(TelemetryPropertyNames.Started_WithHelp, withHelp);\n            SetProperty(TelemetryPropertyNames.Started_WithRun, withRun);\n            SetProperty(TelemetryPropertyNames.Started_WithOtherArgs, withOtherArgs);\n            SetProperty(TelemetryPropertyNames.Started_WithOutputRedirection, withOutputRedirection);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/TelemetryEventBase.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal abstract class TelemetryEventBase\n    {\n        private readonly string _name;\n        private readonly Dictionary<string, string> _properties = new Dictionary<string, string>();\n        private readonly Dictionary<string, double> _measurements = new Dictionary<string, double>();\n\n        public string Name => _name;\n        public IReadOnlyDictionary<string, string> Properties => _properties;\n        public IReadOnlyDictionary<string, double> Measurements => _measurements;\n\n        public TelemetryEventBase(string name)\n        {\n            _name = name;\n        }\n\n        protected void SetProperty(string name, bool value) => SetProperty(name, value.ToString());\n        protected void SetProperty(string name, string value) => _properties[name] = value;\n        protected string GetProperty(string name, string defaultValue = default)\n        {\n            if (_properties.TryGetValue(name, out string value))\n            {\n                return value;\n            }\n\n            return defaultValue;\n        }\n\n        protected void SetMeasurement(string name, double value) => _measurements[name] = value;\n        protected double GetMeasurement(string name, double defaultValue = default)\n        {\n            if (_measurements.TryGetValue(name, out double value))\n            {\n                return value;\n            }\n\n            return defaultValue;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/Events/WebApiF5FixEvent.cs",
    "content": "namespace Microsoft.HttpRepl.Telemetry.Events\n{\n    internal class WebApiF5FixEvent : TelemetryEventBase\n    {\n        public WebApiF5FixEvent(bool skippedByPreference = false) : base(TelemetryEventNames.WebApiF5Fix)\n        {\n            SetProperty(TelemetryPropertyNames.WebApiF5Fix_SkippedByPreference, skippedByPreference);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/TelemetryCommandWrapper.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Telemetry.Events;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal class TelemetryCommandWrapper : ICommand<HttpState, ICoreParseResult>\n    {\n        private readonly ICommand<HttpState, ICoreParseResult> _command;\n        private readonly ITelemetry _telemetry;\n\n        public string Name => _command.Name;\n\n        public ICommand<HttpState, ICoreParseResult> Command => _command;\n\n        public TelemetryCommandWrapper(ITelemetry telemetry, ICommand<HttpState, ICoreParseResult> command)\n        {\n            _telemetry = telemetry;\n            _command = command;\n        }\n\n        public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            return _command.CanHandle(shellState, programState, parseResult);\n        }\n\n        public Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            bool wasSuccessful = true;\n            try\n            {\n                return _command.ExecuteAsync(shellState, programState, parseResult, cancellationToken);\n            }\n            catch\n            {\n                wasSuccessful = false;\n                throw;\n            }\n            finally\n            {\n                _telemetry.TrackEvent(new CommandExecutedEvent(_command.Name, wasSuccessful));\n            }\n        }\n\n        public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            return _command.GetHelpDetails(shellState, programState, parseResult);\n        }\n\n        public string GetHelpSummary(IShellState shellState, HttpState programState)\n        {\n            return _command.GetHelpSummary(shellState, programState);\n        }\n\n        public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)\n        {\n            return _command.Suggest(shellState, programState, parseResult);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/TelemetryConstants.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.txt file in the project root for more information.\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal class TelemetryEventNames\n    {\n        public const string CommandExecuted = nameof(CommandExecuted);\n        public const string Connect = nameof(Connect);\n        public const string HttpCommand = nameof(HttpCommand);\n        public const string Preference = nameof(Preference);\n        public const string SetHeader = nameof(SetHeader);\n        public const string AddQueryParam = nameof(AddQueryParam);\n        public const string ClearQueryParam = nameof(ClearQueryParam);\n        public const string Started = nameof(Started);\n        public const string WebApiF5Fix = nameof(WebApiF5Fix);\n    }\n\n    internal class TelemetryPropertyNames\n    {\n        public const string CommandExecuted_CommandName = \"CommandName\";\n        public const string CommandExecuted_WasSuccessful = \"WasSuccessful\";\n\n        public const string ClearQueryParam_Key = \"QueryParamKey\";\n        public const string ClearQueryParam_IsValueEmpty = \"IsValueEmpty\";\n\n        public const string Connect_BaseSpecified = \"BaseSpecified\";\n        public const string Connect_OpenApiFound = \"OpenApiFound\";\n        public const string Connect_OpenApiSpecified = \"OpenApiSpecified\";\n        public const string Connect_RootSpecified = \"RootSpecified\";\n\n        public const string HttpCommand_HeaderSpecified = \"HeaderSpecified\";\n        public const string HttpCommand_Method = \"Method\";\n        public const string HttpCommand_NoBodySpecified = \"NoBodySpecified\";\n        public const string HttpCommand_NoFormattingSpecified = \"NoFormattingSpecified\";\n        public const string HttpCommand_PathSpecified = \"PathSpecified\";\n        public const string HttpCommand_RequestBodyContentSpecified = \"RequestBodyContentSpecified\";\n        public const string HttpCommand_RequestBodyFileSpecified = \"RequestBodyFileSpecified\";\n        public const string HttpCommand_ResponseHeadersFileSpecified = \"ResponseHeadersFileSpecified\";\n        public const string HttpCommand_ResponseBodyFileSpecified = \"ResponseBodyFileSpecified\";\n        public const string HttpCommand_StreamingSpecified = \"StreamingSpecified\";\n\n        public const string Preference_GetOrSet = \"GetOrSet\";\n        public const string Preference_PreferenceName = \"PreferenceName\";\n\n        public const string SetHeader_HeaderName = \"HeaderName\";\n        public const string SetHeader_IsValueEmpty = \"IsValueEmpty\";\n\n        public const string AddQueryParam_Key = \"QueryParamKey\";\n        public const string AddQueryParam_IsValueEmpty = \"IsValueEmpty\";\n\n        public const string Started_WithHelp = \"WithHelp\";\n        public const string Started_WithOtherArgs = \"WithOtherArgs\";\n        public const string Started_WithOutputRedirection = \"WithOutputRedirection\";\n        public const string Started_WithRun = \"WithRun\";\n\n        public const string WebApiF5Fix_SkippedByPreference = \"SkippedByPreference\";\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/Telemetry/TelemetryExtensions.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.Telemetry.Events;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal static class TelemetryExtensions\n    {\n        public static void TrackEvent(this ITelemetry telemetry, TelemetryEventBase telemetryEvent)\n        {\n            telemetry.TrackEvent(telemetryEvent.Name, telemetryEvent.Properties, telemetryEvent.Measurements);\n        }\n\n        public static void TrackStartedEvent(this ITelemetry telemetry, bool withHelp = false, bool withRun = false, bool withOtherArgs = false, bool withOutputRedirection = false)\n        {\n            telemetry.TrackEvent(new StartedEvent(withHelp, withRun, withOtherArgs, withOutputRedirection));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/UriLauncher.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.txt file in the project root for more information.\n\nusing System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Resources;\n\nnamespace Microsoft.HttpRepl\n{\n    internal class UriLauncher : IUriLauncher\n    {\n        public Task LaunchUriAsync(Uri uri)\n        {\n            string agent;\n            string agentParam;\n\n            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n            {\n                agent = \"cmd\";\n                agentParam = $\"/c start {uri.AbsoluteUri}\";\n            }\n            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))\n            {\n                agent = \"open\";\n                agentParam = uri.AbsoluteUri;\n            }\n            else // Linux\n            {\n                agent = \"xdg-open\";\n                agentParam = uri.AbsoluteUri;\n            }\n\n            Process process = Process.Start(new ProcessStartInfo(agent, agentParam) { CreateNoWindow = true });\n\n            if (process != null)\n            {\n                return Task.CompletedTask;\n            }\n            else\n            {\n                string uriLaunchErrorMessage = string.Format(Strings.UICommand_UnableToLaunchUriError, uri);\n\n                return Task.FromException(new InvalidOperationException(uriLaunchErrorMessage));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/UserProfile/IUserProfileDirectoryProvider.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.txt file in the project root for more information.\n\nnamespace Microsoft.HttpRepl.UserProfile\n{\n    public interface IUserProfileDirectoryProvider\n    {\n        string GetUserProfileDirectory();\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/UserProfile/UserProfileDirectoryProvider.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.txt file in the project root for more information.\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace Microsoft.HttpRepl.UserProfile\n{\n    public class UserProfileDirectoryProvider : IUserProfileDirectoryProvider\n    {\n        public string GetUserProfileDirectory()\n        {\n            bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);\n\n            string profileDir = Environment.GetEnvironmentVariable(isWindows\n                ? \"USERPROFILE\"\n                : \"HOME\");\n\n            return profileDir;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/VersionSensor.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.txt file in the project root for more information.\n\nusing System;\nusing System.Reflection;\n\nnamespace Microsoft.HttpRepl\n{\n    internal class VersionSensor\n    {\n        private static readonly Lazy<BuildInfo> buildInfo = new Lazy<BuildInfo>(() =>\n        {\n            Assembly assembly = typeof(VersionSensor).GetTypeInfo().Assembly;\n\n            BuildInfo buildInfo = new BuildInfo()\n            {\n                AssemblyInformationalVersion = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()\n                                                       .InformationalVersion,\n                AssemblyVersion = assembly.GetName().Version\n            };\n\n            return buildInfo;\n        });\n\n        public static string AssemblyInformationalVersion => buildInfo.Value.AssemblyInformationalVersion;\n        public static Version AssemblyVersion => buildInfo.Value.AssemblyVersion;\n\n        private class BuildInfo\n        {\n            public string AssemblyInformationalVersion { get; internal set; }\n            public Version AssemblyVersion { get; internal set; }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl/WellKnownHeaders.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl\n{\n    public static class WellKnownHeaders\n    {\n        public static readonly string ContentType = \"Content-Type\";\n\n        public static readonly IEnumerable<string> CommonHeaders = new[]\n        {\n            \"A-IM\",\n            \"Accept\",\n            \"Accept-Charset\",\n            \"Accept-Encoding\",\n            \"Accept-Language\",\n            \"Accept-Datetime\",\n            \"Access-Control-Request-Method\",\n            \"Access-Control-Request-Headers\",\n            \"Allow\",\n            \"Authorization\",\n            \"Cache-Control\",\n            \"Connection\",\n            \"Content-Disposition\",\n            \"Content-Encoding\",\n            \"Content-Language\",\n            \"Content-Length\",\n            \"Content-Location\",\n            \"Content-MD5\",\n            \"Content-Range\",\n            ContentType,\n            \"Cookie\",\n            \"Date\",\n            \"Expect\",\n            \"Expires\",\n            \"Forwarded\",\n            \"From\",\n            \"Host\",\n            \"If-Match\",\n            \"If-Modified-Since\",\n            \"If-None-Match\",\n            \"If-Range\",\n            \"If-Unmodified-Since\",\n            \"Last-Modified\",\n            \"Max-Forwards\",\n            \"Origin\",\n            \"Pragma\",\n            \"Proxy-Authentication\",\n            \"Range\",\n            \"Referer\",\n            \"TE\",\n            \"User-Agent\",\n            \"Upgrade\",\n            \"Via\",\n            \"Warning\",\n            //Non-standard\n            \"Upgrade-Insecure-Requests\",\n            \"X-Requested-With\",\n            \"DNT\",\n            \"X-Forwarded-For\",\n            \"X-Forwarded-Host\",\n            \"X-Forwarded-Proto\",\n            \"Front-End-Https\",\n            \"X-Http-Method-Override\",\n            \"X-ATT-DeviceId\",\n            \"X-Wap-Profile\",\n            \"Proxy-Connection\",\n            \"X-UIDH\",\n            \"X-Csrf-Token\",\n            \"X-Request-ID\",\n            \"X-Correlation-ID\"\n        };\n\n        public static readonly IEnumerable<string> ContentHeaders = new []\n        {\n            \"Allow\",\n            \"Content-Disposition\",\n            \"Content-Encoding\",\n            \"Content-Language\",\n            \"Content-Length\",\n            \"Content-Location\",\n            \"Content-MD5\",\n            \"Content-Range\",\n            ContentType,\n            \"Expires\",\n            \"Last-Modified\",\n        };\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/DockerContainerDetectorForTelemetry.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Security;\nusing Microsoft.Win32;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal class DockerContainerDetectorForTelemetry : IDockerContainerDetector\n    {\n        public IsDockerContainer IsDockerContainer()\n        {\n            if (OperatingSystem.IsWindows())\n            {\n                try\n                {\n                    using (RegistryKey subkey\n                        = Registry.LocalMachine.OpenSubKey(\"System\\\\CurrentControlSet\\\\Control\"))\n                    {\n                        return subkey?.GetValue(\"ContainerType\") != null\n                            ? HttpRepl.Telemetry.IsDockerContainer.True\n                            : HttpRepl.Telemetry.IsDockerContainer.False;\n                    }\n                }\n                catch (SecurityException)\n                {\n                    return HttpRepl.Telemetry.IsDockerContainer.Unknown;\n                }\n            }\n            else if (OperatingSystem.IsLinux())\n            {\n                try\n                {\n                    bool isDocker = File\n                        .ReadAllText(\"/proc/1/cgroup\")\n                        .Contains(\"/docker/\", StringComparison.Ordinal);\n\n                    return isDocker\n                        ? HttpRepl.Telemetry.IsDockerContainer.True\n                        : HttpRepl.Telemetry.IsDockerContainer.False;\n                }\n                catch (Exception ex) when (ex is IOException || ex.InnerException is IOException)\n                {\n                    // in some environments (restricted docker container, shared hosting etc.),\n                    // procfs is not accessible and we get UnauthorizedAccessException while the\n                    // inner exception is set to IOException. Ignore and continue when that happens.\n                }\n            }\n            else if (OperatingSystem.IsMacOS())\n            {\n                return HttpRepl.Telemetry.IsDockerContainer.False;\n            }\n\n            return HttpRepl.Telemetry.IsDockerContainer.Unknown;\n        }\n    }\n\n    internal enum IsDockerContainer\n    {\n        True,\n        False,\n        Unknown\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/EnvironmentHelper.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal static class EnvironmentHelper\n    {\n        public static bool GetEnvironmentVariableAsBool(string name, bool defaultValue = false)\n        {\n            var str = Environment.GetEnvironmentVariable(name);\n            if (string.IsNullOrEmpty(str))\n            {\n                return defaultValue;\n            }\n\n            switch (str.ToUpperInvariant())\n            {\n                case \"TRUE\":\n                case \"1\":\n                case \"YES\":\n                    return true;\n                case \"FALSE\":\n                case \"0\":\n                case \"NO\":\n                    return false;\n                default:\n                    return defaultValue;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/FirstTimeUseNoticeSentinel.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\nusing System.IO;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    public sealed class FirstTimeUseNoticeSentinel : IFirstTimeUseNoticeSentinel\n    {\n        public const string SkipFirstTimeExperienceEnvironmentVariableName = \"DOTNET_HTTPREPL_SKIP_FIRST_TIME_EXPERIENCE\";\n\n        private readonly string _sentinel;\n        private readonly string _dotnetTryUserProfileFolderPath;\n        private readonly Func<string, bool> _fileExists;\n        private readonly Func<string, bool> _directoryExists;\n        private readonly Action<string> _createDirectory;\n        private readonly Action<string> _createEmptyFile;\n\n        private string SentinelPath => Path.Combine(_dotnetTryUserProfileFolderPath, _sentinel);\n\n        public FirstTimeUseNoticeSentinel(string productVersion) :\n            this(\n                productVersion,\n                Paths.DotnetUserProfileFolderPath,\n                File.Exists,\n                Directory.Exists,\n                path => Directory.CreateDirectory(path),\n                path => File.WriteAllBytes(path, Array.Empty<byte>()))\n        {\n        }\n\n        public FirstTimeUseNoticeSentinel(\n            string productVersion,\n            string dotnetTryUserProfileFolderPath,\n            Func<string, bool> fileExists,\n            Func<string, bool> directoryExists,\n            Action<string> createDirectory,\n            Action<string> createEmptyFile)\n        {\n            _sentinel = $\"{productVersion}.dotnetHttpReplFirstUseSentinel\";\n            _dotnetTryUserProfileFolderPath = dotnetTryUserProfileFolderPath;\n            _fileExists = fileExists;\n            _directoryExists = directoryExists;\n            _createDirectory = createDirectory;\n            _createEmptyFile = createEmptyFile;\n        }\n\n        public bool Exists()\n        {\n            return _fileExists(SentinelPath);\n        }\n\n        public void CreateIfNotExists()\n        {\n            if (!Exists())\n            {\n                if (!_directoryExists(_dotnetTryUserProfileFolderPath))\n                {\n                    _createDirectory(_dotnetTryUserProfileFolderPath);\n                }\n\n                _createEmptyFile(SentinelPath);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/IDockerContainerDetector.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal interface IDockerContainerDetector\n    {\n        IsDockerContainer IsDockerContainer();\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/IFirstTimeUseNoticeSentinel.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    public interface IFirstTimeUseNoticeSentinel\n    {\n        bool Exists();\n\n        void CreateIfNotExists();\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/ITelemetry.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    public interface ITelemetry\n    {\n        bool Enabled { get; }\n        void TrackEvent(string eventName, IReadOnlyDictionary<string, string> properties, IReadOnlyDictionary<string, double> measurements);\n        IFirstTimeUseNoticeSentinel FirstTimeUseNoticeSentinel { get; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/IUserLevelCacheWriter.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    public interface IUserLevelCacheWriter\n    {\n        string RunWithCache(\n            string cacheKey,\n            Func<string> getValueToCache);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/MacAddressGetter.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Net.NetworkInformation;\nusing System.Runtime.InteropServices;\nusing System.Text.RegularExpressions;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal static class MacAddressGetter\n    {\n        private const string InvalidMacAddress = \"00-00-00-00-00-00\";\n        private const string MacRegex = @\"(?:[a-z0-9]{2}[:\\-]){5}[a-z0-9]{2}\";\n        private const string ZeroRegex = @\"(?:00[:\\-]){5}00\";\n        private const int ErrorFileNotFound = 0x2;\n\n        [SuppressMessage(\"Design\", \"CA1031:Do not catch general exception types\", Justification = \"We don't want any errors in telemetry to cause failures in the product.\")]\n        public static string GetMacAddress()\n        {\n            try\n            {\n                var macAddress = GetMacAddressCore();\n                if (string.IsNullOrWhiteSpace(macAddress) || macAddress.Equals(InvalidMacAddress, StringComparison.OrdinalIgnoreCase))\n                {\n                    return GetMacAddressByNetworkInterface();\n                }\n                else\n                {\n                    return macAddress;\n                }\n            }\n            catch\n            {\n                return null;\n            }\n        }\n\n        private static string GetMacAddressCore()\n        {\n            try\n            {\n                var shelloutput = GetShellOutMacAddressOutput();\n                if (string.IsNullOrWhiteSpace(shelloutput))\n                {\n                    return null;\n                }\n\n                return ParseMACAddress(shelloutput);\n            }\n            catch (Win32Exception e)\n            {\n                if (e.NativeErrorCode == ErrorFileNotFound)\n                {\n                    return GetMacAddressByNetworkInterface();\n                }\n                else\n                {\n                    throw;\n                }\n            }\n        }\n\n        private static string ParseMACAddress(string shelloutput)\n        {\n            foreach (Match match in Regex.Matches(shelloutput, MacRegex, RegexOptions.IgnoreCase))\n            {\n                if (!Regex.IsMatch(match.Value, ZeroRegex))\n                {\n                    return match.Value;\n                }\n            }\n\n            return null;\n        }\n\n        private static string GetIpCommandOutput()\n        {\n            var ipResult = new ProcessStartInfo\n            {\n                FileName = \"ip\",\n                Arguments = \"link\",\n                UseShellExecute = false\n            }.ExecuteAndCaptureOutput(out string ipStdOut, out _);\n\n            if (ipResult == 0)\n            {\n                return ipStdOut;\n            }\n            else\n            {\n                return null;\n            }\n        }\n\n        private static string GetShellOutMacAddressOutput()\n        {\n            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n            {\n                var result = new ProcessStartInfo\n                {\n                    FileName = \"getmac.exe\",\n                    UseShellExecute = false\n                }.ExecuteAndCaptureOutput(out string stdOut, out _);\n\n                if (result == 0)\n                {\n                    return stdOut;\n                }\n                else\n                {\n                    return null;\n                }\n            }\n            else\n            {\n                try\n                {\n                    var ifconfigResult = new ProcessStartInfo\n                    {\n                        FileName = \"ifconfig\",\n                        Arguments = \"-a\",\n                        UseShellExecute = false\n                    }.ExecuteAndCaptureOutput(out string ifconfigStdOut, out string ifconfigStdErr);\n\n                    if (ifconfigResult == 0)\n                    {\n                        return ifconfigStdOut;\n                    }\n                    else\n                    {\n                        return GetIpCommandOutput();\n                    }\n                }\n                catch (Win32Exception e)\n                {\n                    if (e.NativeErrorCode == ErrorFileNotFound)\n                    {\n                        return GetIpCommandOutput();\n                    }\n                    else\n                    {\n                        throw;\n                    }\n                }\n            }\n        }\n\n        private static string GetMacAddressByNetworkInterface()\n        {\n            return GetMacAddressesByNetworkInterface().Where(x => !x.Equals(InvalidMacAddress, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();\n        }\n\n        private static List<string> GetMacAddressesByNetworkInterface()\n        {\n            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();\n            var macs = new List<string>();\n\n            if (nics == null || nics.Length < 1)\n            {\n                macs.Add(string.Empty);\n                return macs;\n            }\n\n            foreach (NetworkInterface adapter in nics)\n            {\n                IPInterfaceProperties properties = adapter.GetIPProperties();\n\n                PhysicalAddress address = adapter.GetPhysicalAddress();\n                byte[] bytes = address.GetAddressBytes();\n                macs.Add(string.Join(\"-\", bytes.Select(x => x.ToString(\"X2\"))));\n                if (macs.Count >= 10)\n                {\n                    break;\n                }\n            }\n            return macs;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/Microsoft.HttpRepl.Telemetry.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <TargetFramework>net8.0</TargetFramework>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.ApplicationInsights.WorkerService\" />\n    <PackageReference Include=\"Microsoft.DotNet.PlatformAbstractions\" />\n    <PackageReference Include=\"Microsoft.Win32.Registry\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/Paths.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\nusing System.IO;\nusing System.Runtime.InteropServices;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal static class Paths\n    {\n        private const string DotnetHomeVariableName = \"DOTNET_CLI_HOME\";\n        private const string DotnetProfileDirectoryName = \".dotnet\";\n        private const string ToolsShimFolderName = \"tools\";\n\n        static Paths()\n        {\n            UserProfile = Environment.GetEnvironmentVariable(\n                RuntimeInformation.IsOSPlatform(OSPlatform.Windows)\n                    ? \"USERPROFILE\"\n                    : \"HOME\");\n\n            DotnetToolsPath = Path.Combine(UserProfile, DotnetProfileDirectoryName, ToolsShimFolderName);\n\n            var nugetPackagesEnvironmentVariable = Environment.GetEnvironmentVariable(\"NUGET_PACKAGES\");\n\n            NugetCache = string.IsNullOrWhiteSpace(nugetPackagesEnvironmentVariable)\n                             ? Path.Combine(UserProfile, \".nuget\", \"packages\")\n                             : nugetPackagesEnvironmentVariable;\n        }\n\n        public static string DotnetUserProfileFolderPath =>\n            Path.Combine(DotnetHomePath, DotnetProfileDirectoryName);\n\n        public static string DotnetHomePath\n        {\n            get\n            {\n                var home = Environment.GetEnvironmentVariable(DotnetHomeVariableName);\n                if (string.IsNullOrEmpty(home))\n                {\n                    home = UserProfile;\n                    if (string.IsNullOrEmpty(home))\n                    {\n                        throw new DirectoryNotFoundException();\n                    }\n                }\n\n                return home;\n            }\n        }\n\n        public static string DotnetToolsPath { get; }\n\n        public static string UserProfile { get; }\n\n        public static string NugetCache { get; }\n\n        public static readonly string InstallDirectory = Path.GetDirectoryName(typeof(Paths).Assembly.Location);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/ProcessStartInfoExtensions.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System.Diagnostics;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal static class ProcessStartInfoExtensions\n    {\n        public static int ExecuteAndCaptureOutput(this ProcessStartInfo startInfo, out string stdOut, out string stdErr)\n        {\n            using var outStream = new StreamForwarder();\n            using var errStream = new StreamForwarder();\n\n            outStream.Capture();\n            errStream.Capture();\n\n            startInfo.RedirectStandardOutput = true;\n            startInfo.RedirectStandardError = true;\n\n            using var process = new Process\n            {\n                StartInfo = startInfo\n            };\n\n            process.EnableRaisingEvents = true;\n\n            process.Start();\n\n            var taskOut = outStream.BeginRead(process.StandardOutput);\n            var taskErr = errStream.BeginRead(process.StandardError);\n\n            process.WaitForExit();\n\n            taskOut.Wait();\n            taskErr.Wait();\n\n            stdOut = outStream.CapturedOutput;\n            stdErr = errStream.CapturedOutput;\n\n            return process.ExitCode;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/Sha256Hasher.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System.Security.Cryptography;\nusing System.Text;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    public static class Sha256Hasher\n    {\n        /// <summary>\n        /// The hashed mac address needs to be the same hashed value as produced by the other distinct sources given the same input. (e.g. VsCode)\n        /// </summary>\n        public static string Hash(string text)\n        {\n            using var sha256 = SHA256.Create();\n            return HashInFormat(sha256, text);\n        }\n\n        private static string HashInFormat(SHA256 sha256, string text)\n        {\n            byte[] bytes = Encoding.UTF8.GetBytes(text);\n            byte[] hash = sha256.ComputeHash(bytes);\n            StringBuilder hashString = new StringBuilder();\n            foreach (byte x in hash)\n            {\n                hashString.AppendFormat(\"{0:x2}\", x);\n            }\n            return hashString.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/StreamForwarder.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    [SuppressMessage(\"Globalization\", \"CA1303:Do not pass literals as localized parameters\", Justification = \"Not doing localization for telemetry yet.\")]\n    public sealed class StreamForwarder : IDisposable\n    {\n        private static readonly char[] s_ignoreCharacters = new char[] { '\\r' };\n        private static readonly char s_flushBuilderCharacter = '\\n';\n\n        private StringBuilder _builder;\n        private StringWriter _capture;\n        private Action<string> _writeLine;\n\n        public string CapturedOutput\n        {\n            get\n            {\n                return _capture?.GetStringBuilder()?.ToString();\n            }\n        }\n\n        public StreamForwarder Capture()\n        {\n            ThrowIfCaptureSet();\n\n            _capture = new StringWriter();\n\n            return this;\n        }\n\n        public StreamForwarder ForwardTo(Action<string> writeLine)\n        {\n            ThrowIfNull(writeLine);\n\n            ThrowIfForwarderSet();\n\n            _writeLine = writeLine;\n\n            return this;\n        }\n\n        public Task BeginRead(TextReader reader)\n        {\n            return Task.Run(() => Read(reader));\n        }\n\n        [SuppressMessage(\"Design\", \"CA1062:Validate arguments of public methods\", Justification = \"CA1062 doesn't understand `is not null`.\")]\n        public void Read(TextReader reader)\n        {\n            var bufferSize = 1;\n\n            char currentCharacter;\n\n            var buffer = new char[bufferSize];\n            _builder = new StringBuilder();\n\n            if (reader is not null)\n            {\n                // Using Read with buffer size 1 to prevent looping endlessly\n                // like we would when using Read() with no buffer\n                while (reader.Read(buffer, 0, bufferSize) > 0)\n                {\n                    currentCharacter = buffer[0];\n\n                    if (currentCharacter == s_flushBuilderCharacter)\n                    {\n                        WriteBuilder();\n                    }\n                    else if (!s_ignoreCharacters.Contains(currentCharacter))\n                    {\n                        _builder.Append(currentCharacter);\n                    }\n                }\n            }\n\n            // Flush anything else when the stream is closed\n            // Which should only happen if someone used console.Write\n            WriteBuilder();\n        }\n\n        private void WriteBuilder()\n        {\n            if (_builder.Length == 0)\n            {\n                return;\n            }\n\n            WriteLine(_builder.ToString());\n            _builder.Clear();\n        }\n\n        private void WriteLine(string str)\n        {\n            if (_capture != null)\n            {\n                _capture.WriteLine(str);\n            }\n\n            if (_writeLine != null)\n            {\n                _writeLine(str);\n            }\n        }\n\n        private void ThrowIfNull(object obj)\n        {\n            if (obj == null)\n            {\n                throw new ArgumentNullException(nameof(obj));\n            }\n        }\n\n        private void ThrowIfForwarderSet()\n        {\n            if (_writeLine != null)\n            {\n                throw new InvalidOperationException(\"WriteLine forwarder set previously\"); // TODO: Localize this?\n            }\n        }\n\n        private void ThrowIfCaptureSet()\n        {\n            if (_capture != null)\n            {\n                throw new InvalidOperationException(\"Already capturing stream!\"); // TODO: Localize this?\n            }\n        }\n\n        public void Dispose()\n        {\n            _capture?.Dispose();\n            _capture = null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/Telemetry.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.ApplicationInsights;\nusing Microsoft.DotNet.PlatformAbstractions;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    [SuppressMessage(\"Design\", \"CA1031:Do not catch general exception types\", Justification = \"We don't want any errors in telemetry to cause failures in the product.\")]\n    [SuppressMessage(\"Naming\", \"CA1724: Type names should not match namespaces\", Justification = \"Keeping it consistent with source implementations.\")]\n    public sealed class Telemetry : ITelemetry\n    {\n        internal static string CurrentSessionId;\n        private TelemetryClient _client;\n        private Dictionary<string, string> _commonProperties;\n        private Dictionary<string, double> _commonMeasurements;\n        private Task _trackEventTask;\n\n        private const string InstrumentationKey = \"469489a6-628b-4bb9-80db-ec670f70d874\";\n        public const string TelemetryOptout = \"DOTNET_HTTPREPL_TELEMETRY_OPTOUT\";\n\n        public Telemetry(\n            string productVersion,\n            IFirstTimeUseNoticeSentinel sentinel = null,\n            string sessionId = null,\n            bool blockThreadInitialization = false)\n        {\n            FirstTimeUseNoticeSentinel = sentinel ?? new FirstTimeUseNoticeSentinel(productVersion);\n            Enabled = !EnvironmentHelper.GetEnvironmentVariableAsBool(TelemetryOptout) && PermissionExists(FirstTimeUseNoticeSentinel);\n\n            if (!Enabled)\n            {\n                return;\n            }\n\n            // Store the session ID in a static field so that it can be reused\n            CurrentSessionId = sessionId ?? Guid.NewGuid().ToString();\n\n            if (blockThreadInitialization)\n            {\n                InitializeTelemetry(productVersion);\n            }\n            else\n            {\n                //initialize in task to offload to parallel thread\n                _trackEventTask = Task.Factory.StartNew(() => InitializeTelemetry(productVersion), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);\n            }\n        }\n\n        public bool Enabled { get; }\n\n        public IFirstTimeUseNoticeSentinel FirstTimeUseNoticeSentinel { get; }\n\n        public static bool SkipFirstTimeExperience => EnvironmentHelper.GetEnvironmentVariableAsBool(HttpRepl.Telemetry.FirstTimeUseNoticeSentinel.SkipFirstTimeExperienceEnvironmentVariableName, false);\n\n        private bool PermissionExists(IFirstTimeUseNoticeSentinel sentinel)\n        {\n            if (sentinel == null)\n            {\n                return false;\n            }\n\n            return sentinel.Exists();\n        }\n\n        public void TrackEvent(string eventName, IReadOnlyDictionary<string, string> properties,\n            IReadOnlyDictionary<string, double> measurements)\n        {\n            if (!Enabled)\n            {\n                return;\n            }\n\n            //continue task in existing parallel thread\n            _trackEventTask = _trackEventTask.ContinueWith(\n                x => TrackEventTask(eventName, properties, measurements),\n                TaskScheduler.Default\n            );\n        }\n\n        private void ThreadBlockingTrackEvent(string eventName, IReadOnlyDictionary<string, string> properties, IReadOnlyDictionary<string, double> measurements)\n        {\n            if (!Enabled)\n            {\n                return;\n            }\n            TrackEventTask(eventName, properties, measurements);\n        }\n\n        private void InitializeTelemetry(string productVersion)\n        {\n            try\n            {\n#pragma warning disable CS0618 // Type or member is obsolete\n                _client = new TelemetryClient();\n#pragma warning restore CS0618 // Type or member is obsolete\n                _client.InstrumentationKey = InstrumentationKey;\n                _client.Context.Session.Id = CurrentSessionId;\n                _client.Context.Device.OperatingSystem = RuntimeEnvironment.OperatingSystem;\n\n                _commonProperties = new TelemetryCommonProperties(productVersion).GetTelemetryCommonProperties();\n                _commonMeasurements = new Dictionary<string, double>();\n            }\n            catch (Exception e)\n            {\n                _client = null;\n                // we dont want to fail the tool if telemetry fails.\n                Debug.Fail(e.ToString());\n            }\n        }\n\n        private void TrackEventTask(\n            string eventName,\n            IReadOnlyDictionary<string, string> properties,\n            IReadOnlyDictionary<string, double> measurements)\n        {\n            if (_client == null)\n            {\n                return;\n            }\n\n            try\n            {\n                Dictionary<string, string> eventProperties = GetEventProperties(properties);\n                Dictionary<string, double> eventMeasurements = GetEventMeasures(measurements);\n\n                _client.TrackEvent(PrependProducerNamespace(eventName), eventProperties, eventMeasurements);\n                _client.Flush();\n            }\n            catch (Exception e)\n            {\n                Debug.Fail(e.ToString());\n            }\n        }\n\n        private static string PrependProducerNamespace(string eventName)\n        {\n            return \"dotnet/httprepl/\" + eventName;\n        }\n\n        private Dictionary<string, double> GetEventMeasures(IReadOnlyDictionary<string, double> measurements)\n        {\n            Dictionary<string, double> eventMeasurements = new Dictionary<string, double>(_commonMeasurements);\n            if (measurements != null)\n            {\n                foreach (KeyValuePair<string, double> measurement in measurements)\n                {\n                    eventMeasurements[measurement.Key] = measurement.Value;\n                }\n            }\n            return eventMeasurements;\n        }\n\n        private Dictionary<string, string> GetEventProperties(IReadOnlyDictionary<string, string> properties)\n        {\n            if (properties != null)\n            {\n                var eventProperties = new Dictionary<string, string>(_commonProperties);\n                foreach (KeyValuePair<string, string> property in properties)\n                {\n                    eventProperties[property.Key] = property.Value;\n                }\n                return eventProperties;\n            }\n            else\n            {\n                return _commonProperties;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/TelemetryCommonProperties.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\nusing RuntimeEnvironment = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    internal class TelemetryCommonProperties\n    {\n        private readonly string _productVersion;\n\n        public TelemetryCommonProperties(\n            string productVersion,\n            Func<string, string> hasher = null,\n            Func<string> getMACAddress = null,\n            IDockerContainerDetector dockerContainerDetector = null,\n            IUserLevelCacheWriter userLevelCacheWriter = null)\n        {\n            _productVersion = productVersion;\n            _hasher = hasher ?? Sha256Hasher.Hash;\n            _getMACAddress = getMACAddress ?? MacAddressGetter.GetMacAddress;\n            _dockerContainerDetector = dockerContainerDetector ?? new DockerContainerDetectorForTelemetry();\n            _userLevelCacheWriter = userLevelCacheWriter ?? new UserLevelCacheWriter(productVersion);\n        }\n\n        private readonly IUserLevelCacheWriter _userLevelCacheWriter;\n        private readonly IDockerContainerDetector _dockerContainerDetector;\n        private readonly Func<string, string> _hasher;\n        private readonly Func<string> _getMACAddress;\n        private const string OSVersion = \"OS Version\";\n        private const string OSPlatform = \"OS Platform\";\n        private const string RuntimeId = \"Runtime Id\";\n        private const string ProductVersion = \"Product Version\";\n        private const string DockerContainer = \"Docker Container\";\n        private const string MachineId = \"Machine ID\";\n        private const string KernelVersion = \"Kernel Version\";\n\n        private const string MachineIdCacheKey = \"MachineId\";\n        private const string IsDockerContainerCacheKey = \"IsDockerContainer\";\n\n        public Dictionary<string, string> GetTelemetryCommonProperties()\n        {\n            return new Dictionary<string, string>\n            {\n                {OSVersion, RuntimeEnvironment.OperatingSystemVersion},\n                {OSPlatform, RuntimeEnvironment.OperatingSystemPlatform.ToString()},\n                {RuntimeId, RuntimeEnvironment.GetRuntimeIdentifier()},\n                {ProductVersion, _productVersion},\n                {DockerContainer, IsDockerContainer()},\n                {MachineId, GetMachineId()},\n                {KernelVersion, GetKernelVersion()}\n            };\n        }\n\n        private string GetMachineId()\n        {\n            return _userLevelCacheWriter.RunWithCache(MachineIdCacheKey, () =>\n            {\n                var macAddress = _getMACAddress();\n                if (macAddress != null)\n                {\n                    return _hasher(macAddress);\n                }\n                else\n                {\n                    return Guid.NewGuid().ToString();\n                }\n            });\n        }\n\n        private string IsDockerContainer()\n        {\n            return _userLevelCacheWriter.RunWithCache(IsDockerContainerCacheKey, () =>\n            {\n                return _dockerContainerDetector.IsDockerContainer().ToString(\"G\");\n            });\n        }\n\n        /// <summary>\n        /// Returns a string identifying the OS kernel.\n        /// For Unix this currently comes from \"uname -srv\".\n        /// For Windows this currently comes from RtlGetVersion().\n        /// </summary>\n        private static string GetKernelVersion()\n        {\n            return RuntimeInformation.OSDescription;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.HttpRepl.Telemetry/UserLevelCacheWriter.cs",
    "content": "// Copyright (c) .NET Foundation and contributors. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\nusing System.IO;\n\nnamespace Microsoft.HttpRepl.Telemetry\n{\n    public sealed class UserLevelCacheWriter : IUserLevelCacheWriter\n    {\n        private readonly string _productVersion;\n        private readonly string _dotnetHttpReplUserProfileFolderPath;\n        private readonly Func<string, bool> _fileExists;\n        private readonly Func<string, bool> _directoryExists;\n        private readonly Action<string> _createDirectory;\n        private readonly Action<string, string> _writeAllText;\n        private readonly Func<string, string> _readAllText;\n\n        public UserLevelCacheWriter(string productVersion) :\n            this(\n                productVersion,\n                Paths.DotnetUserProfileFolderPath,\n                File.Exists,\n                Directory.Exists,\n                path => Directory.CreateDirectory(path),\n                File.WriteAllText,\n                File.ReadAllText)\n        {\n        }\n\n        public UserLevelCacheWriter(\n            string productVersion,\n            string dotnetHttpReplUserProfileFolderPath,\n            Func<string, bool> fileExists,\n            Func<string, bool> directoryExists,\n            Action<string> createDirectory,\n            Action<string, string> writeAllText,\n            Func<string, string> readAllText)\n        {\n            _productVersion = productVersion;\n            _dotnetHttpReplUserProfileFolderPath = dotnetHttpReplUserProfileFolderPath;\n            _fileExists = fileExists;\n            _directoryExists = directoryExists;\n            _createDirectory = createDirectory;\n            _writeAllText = writeAllText;\n            _readAllText = readAllText;\n        }\n\n        public string RunWithCache(string cacheKey, Func<string> getValueToCache)\n        {\n            _ = getValueToCache ?? throw new ArgumentNullException(nameof(getValueToCache));\n\n            var cacheFilepath = GetCacheFilePath(cacheKey);\n            try\n            {\n                if (!_fileExists(cacheFilepath))\n                {\n                    if (!_directoryExists(_dotnetHttpReplUserProfileFolderPath))\n                    {\n                        _createDirectory(_dotnetHttpReplUserProfileFolderPath);\n                    }\n\n                    var runResult = getValueToCache();\n\n                    _writeAllText(cacheFilepath, runResult);\n                    return runResult;\n                }\n                else\n                {\n                    return _readAllText(cacheFilepath);\n                }\n            }\n            catch (Exception ex)\n            {\n                if (ex is UnauthorizedAccessException\n                    || ex is PathTooLongException\n                    || ex is IOException)\n                {\n                    return getValueToCache();\n                }\n\n                throw;\n            }\n        }\n\n        private string GetCacheFilePath(string cacheKey)\n        {\n            return Path.Combine(_dotnetHttpReplUserProfileFolderPath, $\"{_productVersion}_{cacheKey}.dotnetHttpReplUserLevelCache\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/CommandHistory.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public class CommandHistory : ICommandHistory\n    {\n        private readonly int _maxEntries;\n        private readonly List<string> _commandLines = new List<string>();\n        private int _currentCommand = -1;\n        private int _suspensionDepth;\n\n        public CommandHistory(int maxEntries = 50)\n        {\n            _maxEntries = maxEntries;\n        }\n\n        public void AddCommand(string command)\n        {\n            if (_suspensionDepth > 0)\n            {\n                return;\n            }\n\n            _commandLines.Add(command);\n            if (_commandLines.Count > _maxEntries)\n            {\n                _commandLines.RemoveAt(0);\n            }\n            _currentCommand = -1;\n        }\n\n        public string GetNextCommand()\n        {\n            if (_commandLines.Count == 0)\n            {\n                return string.Empty;\n            }\n\n            if (_currentCommand == -1 || _currentCommand >= _commandLines.Count - 1)\n            {\n                _currentCommand = -1;\n                return string.Empty;\n            }\n\n            return _commandLines[++_currentCommand];\n        }\n\n        public string GetPreviousCommand()\n        {\n            if (_commandLines.Count == 0)\n            {\n                return string.Empty;\n            }\n\n            if (_currentCommand == -1)\n            {\n                _currentCommand = _commandLines.Count;\n            }\n\n            if (_currentCommand > 0)\n            {\n                return _commandLines[--_currentCommand];\n            }\n\n            return _commandLines[0];\n        }\n\n        public IDisposable SuspendHistory()\n        {\n            ++_suspensionDepth;\n            return new Disposable(() => --_suspensionDepth);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/CommandInputLocation.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.txt file in the project root for more information.\n\nnamespace Microsoft.Repl.Commanding\n{\n    public enum CommandInputLocation\n    {\n        CommandName,\n        Argument,\n        OptionName,\n        OptionValue\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/CommandInputProcessingIssue.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.txt file in the project root for more information.\n\nnamespace Microsoft.Repl.Commanding\n{\n    public class CommandInputProcessingIssue\n    {\n        public CommandInputProcessingIssueKind Kind { get; }\n\n        public string Text { get; }\n\n        public CommandInputProcessingIssue(CommandInputProcessingIssueKind kind, string text)\n        {\n            Kind = kind;\n            Text = text;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/CommandInputProcessingIssueKind.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.txt file in the project root for more information.\n\nnamespace Microsoft.Repl.Commanding\n{\n    public enum CommandInputProcessingIssueKind\n    {\n        CommandMismatch,\n        ArgumentCountOutOfRange,\n        UnknownOption,\n        OptionUseCountOutOfRange,\n        MissingRequiredOptionInput,\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/CommandInputSpecification.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public class CommandInputSpecification\n    {\n        public IReadOnlyList<IReadOnlyList<string>> CommandName { get; }\n\n        public char OptionPreamble { get; }\n\n        public int MinimumArguments { get; }\n\n        public int MaximumArguments { get; }\n\n        public IReadOnlyList<CommandOptionSpecification> Options { get; }\n\n        public CommandInputSpecification(IReadOnlyList<IReadOnlyList<string>> name, char optionPreamble, IReadOnlyList<CommandOptionSpecification> options, int minimumArgs, int maximumArgs)\n        {\n            CommandName = name;\n            OptionPreamble = optionPreamble;\n            MinimumArguments = minimumArgs;\n            MaximumArguments = maximumArgs;\n\n            if (MinimumArguments < 0)\n            {\n                MinimumArguments = 0;\n            }\n\n            if (MaximumArguments < MinimumArguments)\n            {\n                MaximumArguments = MinimumArguments;\n            }\n\n            Options = options;\n        }\n\n        public static CommandInputSpecificationBuilder Create(string baseName, params string[] additionalNameParts)\n        {\n            List<string> nameParts = new List<string> {baseName};\n            nameParts.AddRange(additionalNameParts);\n            return new CommandInputSpecificationBuilder(nameParts);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/CommandInputSpecificationBuilder.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public class CommandInputSpecificationBuilder\n    {\n        private readonly List<IReadOnlyList<string>> _name;\n        private char _optionPreamble;\n        private int _minimumArgs;\n        private int _maximumArgs;\n        private readonly List<CommandOptionSpecification> _options = new List<CommandOptionSpecification>();\n\n        public CommandInputSpecificationBuilder(IReadOnlyList<string> name)\n        {\n            _name = new List<IReadOnlyList<string>> { name };\n            _optionPreamble = '-';\n        }\n\n        public CommandInputSpecificationBuilder WithOptionPreamble(char optionChar)\n        {\n            _optionPreamble = optionChar;\n            return this;\n        }\n\n        public CommandInputSpecificationBuilder ExactArgCount(int count)\n        {\n            _minimumArgs = count;\n            _maximumArgs = count;\n            return this;\n        }\n\n        public CommandInputSpecificationBuilder MinimumArgCount(int count)\n        {\n            _minimumArgs = count;\n            if (_maximumArgs < count)\n            {\n                _maximumArgs = count;\n            }\n\n            return this;\n        }\n\n        public CommandInputSpecificationBuilder MaximumArgCount(int count)\n        {\n            _maximumArgs = count;\n\n            if (_minimumArgs > count)\n            {\n                _minimumArgs = count;\n            }\n\n            return this;\n        }\n\n        public CommandInputSpecificationBuilder WithOption(CommandOptionSpecification option)\n        {\n            _options.Add(option);\n            return this;\n        }\n\n        public CommandInputSpecification Finish()\n        {\n            return new CommandInputSpecification(_name, _optionPreamble, _options, _minimumArgs, _maximumArgs);\n        }\n\n        public CommandInputSpecificationBuilder AlternateName(string baseName, params string[] additionalNameParts)\n        {\n            List<string> nameParts = new List<string> { baseName };\n            nameParts.AddRange(additionalNameParts);\n            _name.Add(nameParts);\n            return this;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/CommandOptionSpecification.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public class CommandOptionSpecification\n    {\n        public string Id { get; }\n\n        public IReadOnlyList<string> Forms { get; }\n\n        public int MaximumOccurrences { get; }\n\n        public int MinimumOccurrences { get; }\n\n        public bool AcceptsValue { get; }\n\n        public bool RequiresValue { get; }\n\n        public CommandOptionSpecification(string id, bool acceptsValue = false, bool requiresValue = false, int minimumOccurrences = 0, int maximumOccurrences = int.MaxValue, params string[] forms)\n        {\n            Id = id;\n            Forms = forms;\n            MinimumOccurrences = minimumOccurrences;\n            MaximumOccurrences = maximumOccurrences > minimumOccurrences ? maximumOccurrences : minimumOccurrences;\n            RequiresValue = requiresValue;\n            AcceptsValue = RequiresValue || acceptsValue;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/CommandWithStructuredInputBase.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public abstract class CommandWithStructuredInputBase<TProgramState, TParseResult> : ICommand<TProgramState, TParseResult>\n        where TParseResult : ICoreParseResult\n    {\n        public abstract string Name { get; }\n\n        public abstract string GetHelpSummary(IShellState shellState, TProgramState programState);\n\n        public string GetHelpDetails(IShellState shellState, TProgramState programState, TParseResult parseResult)\n        {\n            if (!DefaultCommandInput<TParseResult>.TryProcess(InputSpec, parseResult, out DefaultCommandInput<TParseResult> commandInput, out IReadOnlyList<CommandInputProcessingIssue> processingIssues)\n                && processingIssues.Any(x => x.Kind == CommandInputProcessingIssueKind.CommandMismatch))\n            {\n                //If this is the right command, just not the right syntax, report the usage errors\n                return null;\n            }\n\n            return GetHelpDetails(shellState, programState, commandInput, parseResult);\n        }\n\n        protected abstract string GetHelpDetails(IShellState shellState, TProgramState programState, DefaultCommandInput<TParseResult> commandInput, TParseResult parseResult);\n\n        public IEnumerable<string> Suggest(IShellState shellState, TProgramState programState, TParseResult parseResult)\n        {\n            DefaultCommandInput<TParseResult>.TryProcess(InputSpec, parseResult, out DefaultCommandInput<TParseResult> commandInput, out IReadOnlyList<CommandInputProcessingIssue> _);\n\n            string normalCompletionString = parseResult.SelectedSection == parseResult.Sections.Count\n                ? string.Empty\n                : parseResult.Sections[parseResult.SelectedSection].Substring(0, parseResult.CaretPositionWithinSelectedSection);\n\n\n            // Check the various command name permutations to see if we might be completing one of them\n            IReadOnlyList<string> commandName = null;\n            for (int j = 0; j < InputSpec.CommandName.Count; ++j)\n            {\n                IReadOnlyList<string> currentCommandNameParts = InputSpec.CommandName[j];\n\n                //If we're completing in a name position, offer completion for the command name\n                if (parseResult.SelectedSection < currentCommandNameParts.Count)\n                {\n                    bool success = true;\n                    for (int i = 0; i < parseResult.SelectedSection; ++i)\n                    {\n                        string currentCommandNamePart = currentCommandNameParts[i];\n                        string currentParseSection = parseResult.Sections[i];\n                        if (!string.Equals(currentCommandNamePart, currentParseSection, StringComparison.OrdinalIgnoreCase))\n                        {\n                            success = false;\n                            break;\n                        }\n                    }\n\n                    if (success)\n                    {\n                        commandName = currentCommandNameParts;\n                        break;\n                    }\n                }\n            }\n\n            if (commandName?.Count > parseResult.SelectedSection && commandName[parseResult.SelectedSection].StartsWith(normalCompletionString, StringComparison.OrdinalIgnoreCase))\n            {\n                return new[] { commandName[parseResult.SelectedSection] };\n            }\n\n            if (commandInput is null)\n            {\n                return null;\n            }\n\n            if (normalCompletionString.StartsWith(InputSpec.OptionPreamble.ToString(), StringComparison.OrdinalIgnoreCase))\n            {\n                return GetOptionCompletions(commandInput, normalCompletionString);\n            }\n\n            IEnumerable<string> completions = Enumerable.Empty<string>();\n            CommandInputLocation? inputLocation = commandInput.SelectedElement?.Location;\n\n            if (inputLocation != CommandInputLocation.OptionValue && commandInput.Arguments.Count < InputSpec.MaximumArguments)\n            {\n                IEnumerable<string> results = GetArgumentSuggestionsForText(shellState, programState, parseResult, commandInput, normalCompletionString);\n\n                if (results != null)\n                {\n                    completions = results;\n                }\n            }\n\n            switch (inputLocation)\n            {\n                case CommandInputLocation.OptionName:\n                {\n                    IEnumerable<string> results = GetOptionCompletions(commandInput, normalCompletionString);\n\n                    if (results != null)\n                    {\n                        completions = completions.Union(results);\n                    }\n\n                    break;\n                }\n                case CommandInputLocation.OptionValue:\n                {\n                    IEnumerable<string> results = GetOptionValueCompletions(shellState, programState, commandInput.SelectedElement.Owner.NormalizedText, commandInput, parseResult, normalCompletionString);\n\n                    if (results != null)\n                    {\n                        completions = completions.Union(results);\n                    }\n\n                    break;\n                }\n                case CommandInputLocation.Argument:\n                {\n                    IEnumerable<string> argumentResults = GetArgumentSuggestionsForText(shellState, programState, parseResult, commandInput, normalCompletionString);\n\n                    if (argumentResults != null)\n                    {\n                        completions = completions.Union(argumentResults);\n                    }\n\n                    if (string.IsNullOrEmpty(normalCompletionString))\n                    {\n                        IEnumerable<string> results = GetOptionCompletions(commandInput, normalCompletionString);\n\n                        if (results != null)\n                        {\n                            completions = completions.Union(results);\n                        }\n                    }\n\n                    break;\n                }\n            }\n\n            return completions;\n        }\n\n        protected virtual IEnumerable<string> GetOptionValueCompletions(IShellState shellState, TProgramState programState, string optionId, DefaultCommandInput<TParseResult> commandInput, TParseResult parseResult, string normalizedCompletionText)\n        {\n            return null;\n        }\n\n        protected virtual IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, TProgramState programState, TParseResult parseResult, DefaultCommandInput<TParseResult> commandInput, string normalCompletionString)\n        {\n            return null;\n        }\n\n        private IEnumerable<string> GetOptionCompletions(DefaultCommandInput<TParseResult> commandInput, string normalCompletionString)\n        {\n            return InputSpec.Options.Where(x => commandInput.Options[x.Id].Count < x.MaximumOccurrences)\n                .SelectMany(x => x.Forms)\n                .Where(x => x.StartsWith(normalCompletionString, StringComparison.OrdinalIgnoreCase));\n        }\n\n        public bool? CanHandle(IShellState shellState, TProgramState programState, TParseResult parseResult)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            if (!DefaultCommandInput<TParseResult>.TryProcess(InputSpec, parseResult, out DefaultCommandInput<TParseResult> commandInput, out IReadOnlyList<CommandInputProcessingIssue> processingIssues))\n            {\n                //If this is the right command, just not the right syntax, report the usage errors\n                if (processingIssues.All(x => x.Kind != CommandInputProcessingIssueKind.CommandMismatch))\n                {\n                    foreach (CommandInputProcessingIssue issue in processingIssues)\n                    {\n                        shellState.ConsoleManager.Error.WriteLine(GetStringForIssue(issue));\n                    }\n\n                    string help = GetHelpDetails(shellState, programState, parseResult);\n                    shellState.ConsoleManager.WriteLine(help);\n                    return false;\n                }\n\n                //If there was a mismatch in the command name, this isn't our input to handle\n                return null;\n            }\n\n            return CanHandle(shellState, programState, commandInput);\n        }\n\n        protected virtual bool CanHandle(IShellState shellState, TProgramState programState, DefaultCommandInput<TParseResult> commandInput)\n        {\n            return true;\n        }\n\n        protected virtual string GetStringForIssue(CommandInputProcessingIssue issue)\n        {\n            issue = issue ?? throw new ArgumentNullException(nameof(issue));\n\n            //TODO: Make this nicer\n            return issue.Kind + \" -- \" + issue.Text;\n        }\n\n        public Task ExecuteAsync(IShellState shellState, TProgramState programState, TParseResult parseResult, CancellationToken cancellationToken)\n        {\n            if (!DefaultCommandInput<TParseResult>.TryProcess(InputSpec, parseResult, out DefaultCommandInput<TParseResult> commandInput, out IReadOnlyList<CommandInputProcessingIssue> _))\n            {\n                return Task.CompletedTask;\n            }\n\n            return ExecuteAsync(shellState, programState, commandInput, parseResult, cancellationToken);\n        }\n\n        protected abstract Task ExecuteAsync(IShellState shellState, TProgramState programState, DefaultCommandInput<TParseResult> commandInput, TParseResult parseResult, CancellationToken cancellationToken);\n\n        public abstract CommandInputSpecification InputSpec { get; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/DefaultCommandDispatcher.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public static class DefaultCommandDispatcher\n    {\n        public static DefaultCommandDispatcher<TProgramState> Create<TProgramState>(Func<string> getPrompt, TProgramState programState)\n        {\n            return new DefaultCommandDispatcher<TProgramState>(getPrompt, programState);\n        }\n\n        public static DefaultCommandDispatcher<TProgramState> Create<TProgramState>(Action<IShellState> onReady, TProgramState programState)\n        {\n            return new DefaultCommandDispatcher<TProgramState>(onReady, programState);\n        }\n\n        public static DefaultCommandDispatcher<TProgramState, TParseResult> Create<TProgramState, TParseResult>(Func<string> getPrompt, TProgramState programState, IParser<TParseResult> parser)\n            where TParseResult : ICoreParseResult\n        {\n            return new DefaultCommandDispatcher<TProgramState, TParseResult>(getPrompt, programState, parser);\n        }\n\n        public static DefaultCommandDispatcher<TProgramState, TParseResult> Create<TProgramState, TParseResult>(Action<IShellState> onReady, TProgramState programState, IParser<TParseResult> parser)\n            where TParseResult : ICoreParseResult\n        {\n            return new DefaultCommandDispatcher<TProgramState, TParseResult>(onReady, programState, parser);\n        }\n    }\n\n    public class DefaultCommandDispatcher<TProgramState> : DefaultCommandDispatcher<TProgramState, ICoreParseResult>\n    {\n        public DefaultCommandDispatcher(Func<string> getPrompt, TProgramState programState)\n            : base(getPrompt, programState, new CoreParser())\n        {\n        }\n\n        public DefaultCommandDispatcher(Action<IShellState> onReady, TProgramState programState)\n            : base(onReady, programState, new CoreParser())\n        {\n        }\n    }\n\n    public class DefaultCommandDispatcher<TProgramState, TParseResult> : ICommandDispatcher<TProgramState, TParseResult>\n        where TParseResult : ICoreParseResult\n    {\n        private readonly Action<IShellState> _onReady;\n        private readonly TProgramState _programState;\n        private readonly IParser<TParseResult> _parser;\n        private readonly HashSet<ICommand<TProgramState, TParseResult>> _commands = new HashSet<ICommand<TProgramState, TParseResult>>();\n        private bool _isReady;\n\n        public DefaultCommandDispatcher(Func<string> getPrompt, TProgramState programState, IParser<TParseResult> parser)\n            : this(s => s.ConsoleManager.Write(getPrompt()), programState, parser)\n        {\n        }\n\n        public DefaultCommandDispatcher(Action<IShellState> onReady, TProgramState programState, IParser<TParseResult> parser)\n        {\n            _onReady = onReady;\n            _programState = programState;\n            _parser = parser;\n        }\n\n        public void AddCommand(ICommand<TProgramState, TParseResult> command)\n        {\n            _commands.Add(command);\n        }\n\n        public IEnumerable<ICommand<TProgramState, TParseResult>> Commands => _commands;\n\n        public IParser Parser => _parser;\n\n        public IReadOnlyList<string> CollectSuggestions(IShellState shellState)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            string line = shellState.InputManager.GetCurrentBuffer();\n            TParseResult parseResult = _parser.Parse(line, shellState.InputManager.CaretPosition);\n            HashSet<string> suggestions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\n\n            foreach (ICommand<TProgramState, TParseResult> command in _commands)\n            {\n                IEnumerable<string> commandSuggestions = command.Suggest(shellState, _programState, parseResult);\n\n                if (commandSuggestions != null)\n                {\n                    suggestions.UnionWith(commandSuggestions);\n                }\n            }\n\n            return suggestions.OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList();\n        }\n\n        public async Task ExecuteCommandAsync(IShellState shellState, CancellationToken cancellationToken)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            _isReady = false;\n            shellState.ConsoleManager.WriteLine();\n            string commandText = shellState.InputManager.GetCurrentBuffer();\n\n            if (!string.IsNullOrWhiteSpace(commandText))\n            {\n                shellState.CommandHistory.AddCommand(shellState.InputManager.GetCurrentBuffer());\n\n                try\n                {\n                    await ExecuteCommandInternalAsync(shellState, cancellationToken).ConfigureAwait(false);\n                }\n                catch (Exception ex)\n                {\n                    shellState.ConsoleManager.Error.WriteLine(ex.ToString().Bold().Red());\n                }\n\n                if (cancellationToken.IsCancellationRequested)\n                {\n                    shellState.ConsoleManager.Error.WriteLine(Resources.Strings.DefaultCommandDispatcher_Error_ExecutionWasCancelled.Bold().Red());\n                }\n            }\n\n            if (!_isReady && !shellState.IsExiting)\n            {\n                shellState.ConsoleManager.WriteLine();\n                OnReady(shellState);\n            }\n\n            shellState.InputManager.ResetInput();\n        }\n\n        private async Task ExecuteCommandInternalAsync(IShellState shellState, CancellationToken cancellationToken)\n        {\n            string line = shellState.InputManager.GetCurrentBuffer();\n            TParseResult parseResult = _parser.Parse(line, shellState.InputManager.CaretPosition);\n\n            if (!string.IsNullOrWhiteSpace(parseResult.CommandText))\n            {\n                foreach (ICommand<TProgramState, TParseResult> command in _commands)\n                {\n                    bool? result = command.CanHandle(shellState, _programState, parseResult);\n\n                    if (result.HasValue)\n                    {\n                        if (result.Value)\n                        {\n                            await command.ExecuteAsync(shellState, _programState, parseResult, cancellationToken);\n                        }\n\n                        //If the handler returned non-null, the input would be directed to it, but it's not valid input\n                        return;\n                    }\n                }\n\n                shellState.ConsoleManager.Error.WriteLine(Resources.Strings.DefaultCommandDispatcher_Error_NoMatchingCommand.Red().Bold());\n                shellState.ConsoleManager.Error.WriteLine(Resources.Strings.DefaultCommandDispatcher_Error_SeeHelp.Red().Bold());\n            }\n        }\n\n        public void OnReady(IShellState shellState)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            if (!_isReady && !shellState.IsExiting)\n            {\n                _onReady(shellState);\n                shellState.InputManager.ResetInput();\n                _isReady = true;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/DefaultCommandInput.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public class DefaultCommandInput<TParseResult>\n        where TParseResult : ICoreParseResult\n    {\n        public DefaultCommandInput(IReadOnlyList<InputElement> commandName, IReadOnlyList<InputElement> arguments, IReadOnlyDictionary<string, IReadOnlyList<InputElement>> options, InputElement selectedElement)\n        {\n            CommandName = commandName;\n            Arguments = arguments;\n            Options = options;\n            SelectedElement = selectedElement;\n        }\n\n        public static bool TryProcess(CommandInputSpecification spec, TParseResult parseResult, out DefaultCommandInput<TParseResult> result, out IReadOnlyList<CommandInputProcessingIssue> processingIssues)\n        {\n            spec = spec ?? throw new ArgumentNullException(nameof(spec));\n\n            List<CommandInputProcessingIssue> issues = null;\n            List<InputElement> commandNameElements = null;\n\n            foreach (IReadOnlyList<string> commandName in spec.CommandName)\n            {\n                if (TryProcessCommandName(commandName, parseResult, out List<InputElement> nameElements, out issues))\n                {\n                    commandNameElements = nameElements;\n                    break;\n                }\n            }\n\n            if (commandNameElements is null)\n            {\n                result = null;\n                processingIssues = issues;\n                return false;\n            }\n\n            List<InputElement> arguments = new List<InputElement>();\n            Dictionary<InputElement, InputElement> options = new Dictionary<InputElement, InputElement>();\n            InputElement currentOption = null;\n            CommandOptionSpecification currentOptionSpec = null;\n            InputElement selectedElement = null;\n\n            for (int i = commandNameElements.Count; i < parseResult.Sections.Count; ++i)\n            {\n                //If we're not looking at an option name\n                if (!parseResult.Sections[i].StartsWith(spec.OptionPreamble.ToString(), StringComparison.OrdinalIgnoreCase) || parseResult.IsQuotedSection(i))\n                {\n                    if (currentOption is null)\n                    {\n                        InputElement currentElement = new InputElement(CommandInputLocation.Argument, parseResult.Sections[i], parseResult.Sections[i], i);\n\n                        if (i == parseResult.SelectedSection)\n                        {\n                            selectedElement = currentElement;\n                        }\n\n                        arguments.Add(currentElement);\n                    }\n                    else\n                    {\n                        //If the option isn't a defined one or it is and indicates that it accepts a value, add the section as an option value,\n                        //  otherwise add it as an argument\n                        if (currentOptionSpec?.AcceptsValue ?? true)\n                        {\n                            InputElement currentElement = new InputElement(currentOption, CommandInputLocation.OptionValue, parseResult.Sections[i], parseResult.Sections[i], i);\n\n                            if (i == parseResult.SelectedSection)\n                            {\n                                selectedElement = currentElement;\n                            }\n\n                            options[currentOption] = currentElement;\n                            currentOption = null;\n                            currentOptionSpec = null;\n                        }\n                        else\n                        {\n                            InputElement currentElement = new InputElement(CommandInputLocation.Argument, parseResult.Sections[i], parseResult.Sections[i], i);\n\n                            if (i == parseResult.SelectedSection)\n                            {\n                                selectedElement = currentElement;\n                            }\n\n                            arguments.Add(currentElement);\n                        }\n                    }\n                }\n                //If we are looking at an option name\n                else\n                {\n                    //Otherwise, check to see whether the previous option had a required argument before committing it\n                    if (currentOption is object)\n                    {\n                        options[currentOption] = null;\n\n                        if (currentOptionSpec?.RequiresValue ?? false)\n                        {\n                            issues.Add(new CommandInputProcessingIssue(CommandInputProcessingIssueKind.MissingRequiredOptionInput, currentOption.Text));\n                        }\n                    }\n\n                    CommandOptionSpecification optionSpec = spec.Options.FirstOrDefault(x => x.Forms.Any(y => string.Equals(y, parseResult.Sections[i], StringComparison.Ordinal)));\n\n                    if (optionSpec is null)\n                    {\n                        issues.Add(new CommandInputProcessingIssue(CommandInputProcessingIssueKind.UnknownOption, parseResult.Sections[i]));\n                    }\n\n                    currentOption = new InputElement(CommandInputLocation.OptionName, parseResult.Sections[i], optionSpec?.Id, i);\n\n                    if (i == parseResult.SelectedSection)\n                    {\n                        selectedElement = currentOption;\n                    }\n\n                    currentOptionSpec = optionSpec;\n                }\n            }\n\n            //Clear any option in progress\n            if (currentOption is object)\n            {\n                options[currentOption] = null;\n\n                if (currentOptionSpec?.RequiresValue ?? false)\n                {\n                    issues.Add(new CommandInputProcessingIssue(CommandInputProcessingIssueKind.MissingRequiredOptionInput, currentOption.Text));\n                }\n            }\n\n            //Check to make sure our argument count is in range, if not add an issue\n            if (arguments.Count > spec.MaximumArguments || arguments.Count < spec.MinimumArguments)\n            {\n                issues.Add(new CommandInputProcessingIssue(CommandInputProcessingIssueKind.ArgumentCountOutOfRange, arguments.Count.ToString()));\n            }\n\n            //Build up the dictionary of options by normal form, then validate counts for every option in the spec\n            Dictionary<string, IReadOnlyList<InputElement>> optionsByNormalForm = new Dictionary<string, IReadOnlyList<InputElement>>(StringComparer.Ordinal);\n\n            foreach (KeyValuePair<InputElement, InputElement> entry in options)\n            {\n                if (entry.Key.NormalizedText is null)\n                {\n                    continue;\n                }\n\n                if (!optionsByNormalForm.TryGetValue(entry.Key.NormalizedText, out IReadOnlyList<InputElement> rawBucket))\n                {\n                    optionsByNormalForm[entry.Key.NormalizedText] = rawBucket = new List<InputElement>();\n                }\n\n                List<InputElement> bucket = (List<InputElement>) rawBucket;\n                bucket.Add(entry.Value);\n            }\n\n            foreach (CommandOptionSpecification optionSpec in spec.Options)\n            {\n                if (!optionsByNormalForm.TryGetValue(optionSpec.Id, out IReadOnlyList<InputElement> values))\n                {\n                    optionsByNormalForm[optionSpec.Id] = values = new List<InputElement>();\n                }\n\n                if (values.Count < optionSpec.MinimumOccurrences || values.Count > optionSpec.MaximumOccurrences)\n                {\n                    issues.Add(new CommandInputProcessingIssue(CommandInputProcessingIssueKind.OptionUseCountOutOfRange, values.Count.ToString()));\n                }\n            }\n\n            result = new DefaultCommandInput<TParseResult>(commandNameElements, arguments, optionsByNormalForm, selectedElement);\n            processingIssues = issues;\n            return issues.Count == 0;\n        }\n\n        private static bool TryProcessCommandName(IReadOnlyList<string> commandName, TParseResult parseResult, out List<InputElement> nameElements, out List<CommandInputProcessingIssue> processingIssues)\n        {\n            List<CommandInputProcessingIssue> issues = new List<CommandInputProcessingIssue>();\n            List<InputElement> commandNameElements = new List<InputElement>();\n\n            if (commandName.Count > parseResult.Sections.Count)\n            {\n                issues.Add(new CommandInputProcessingIssue(CommandInputProcessingIssueKind.CommandMismatch, commandName[parseResult.Sections.Count]));\n            }\n\n            for (int i = 0; i < commandName.Count && i < parseResult.Sections.Count; ++i)\n            {\n                if (!string.Equals(commandName[i], parseResult.Sections[i], StringComparison.OrdinalIgnoreCase))\n                {\n                    issues.Add(new CommandInputProcessingIssue(CommandInputProcessingIssueKind.CommandMismatch, parseResult.Sections[i]));\n                }\n\n                commandNameElements.Add(new InputElement(CommandInputLocation.CommandName, parseResult.Sections[i], commandName[i], i));\n            }\n\n            processingIssues = issues;\n\n            //If we have a command name mismatch, no point in continuing\n            if (issues.Count > 0)\n            {\n                nameElements = null;\n                return false;\n            }\n\n            nameElements = commandNameElements;\n            return true;\n        }\n\n        public InputElement SelectedElement { get; }\n\n        public IReadOnlyList<InputElement> CommandName { get; }\n\n        public IReadOnlyList<InputElement> Arguments { get; }\n\n        public IReadOnlyDictionary<string, IReadOnlyList<InputElement>> Options { get; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/ICommand.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public interface ICommand<in TProgramState, in TParseResult>\n        where TParseResult : ICoreParseResult\n    {\n        /// <summary>\n        /// Identifies the command in telemetry events.\n        /// </summary>\n        string Name { get; }\n\n        string GetHelpSummary(IShellState shellState, TProgramState programState);\n\n        string GetHelpDetails(IShellState shellState, TProgramState programState, TParseResult parseResult);\n\n        IEnumerable<string> Suggest(IShellState shellState, TProgramState programState, TParseResult parseResult);\n\n        bool? CanHandle(IShellState shellState, TProgramState programState, TParseResult parseResult);\n\n        Task ExecuteAsync(IShellState shellState, TProgramState programState, TParseResult parseResult, CancellationToken cancellationToken);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/ICommandDispatcher.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public interface ICommandDispatcher\n    {\n        IParser Parser { get; }\n\n        IReadOnlyList<string> CollectSuggestions(IShellState shellState);\n\n        void OnReady(IShellState shellState);\n\n        Task ExecuteCommandAsync(IShellState shellState, CancellationToken cancellationToken);\n    }\n\n    public interface ICommandDispatcher<in TProgramState, in TParseResult> : ICommandDispatcher\n        where TParseResult : ICoreParseResult\n    {\n        IEnumerable<ICommand<TProgramState, TParseResult>> Commands { get; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/ICommandHistory.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.txt file in the project root for more information.\n\nusing System;\n\nnamespace Microsoft.Repl.Commanding\n{\n    public interface ICommandHistory\n    {\n        string GetPreviousCommand();\n\n        string GetNextCommand();\n\n        void AddCommand(string command);\n\n        IDisposable SuspendHistory();\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Commanding/InputElement.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.txt file in the project root for more information.\n\nnamespace Microsoft.Repl.Commanding\n{\n    public class InputElement\n    {\n        public CommandInputLocation Location { get; }\n\n        public string Text { get; }\n\n        public string NormalizedText { get; }\n\n        public InputElement Owner { get; }\n\n        public int ParseResultSectionIndex { get; }\n\n        public InputElement(CommandInputLocation location, string text, string normalizedText, int sectionIndex)\n            : this(null, location, text, normalizedText, sectionIndex)\n        {\n        }\n\n        public InputElement(InputElement owner, CommandInputLocation location, string text, string normalizedText, int sectionIndex)\n        {\n            Owner = owner;\n            Location = location;\n            Text = text;\n            NormalizedText = normalizedText;\n            ParseResultSectionIndex = sectionIndex;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ConsoleHandling/AllowedColors.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.txt file in the project root for more information.\n\nusing System;\n\nnamespace Microsoft.Repl.ConsoleHandling\n{\n    // The values for the non-bold colors come from the ANSI escape sequences,\n    // specifically the SGR foreground codes, which can be referenced here:\n    // https://en.wikipedia.org/wiki/ANSI_escape_code#Colors\n    [Flags]\n    public enum AllowedColors\n    {\n        None = 0x0,\n        Black = 0x1E,\n        BoldBlack = Bold | Black,\n        Red = 0x1F,\n        BoldRed = Bold | Red,\n        Green = 0x20,\n        BoldGreen = Bold | Green,\n        Yellow = 0x21,\n        BoldYellow = Bold | Yellow,\n        Blue = 0x22,\n        BoldBlue = Bold | Blue,\n        Magenta = 0x23,\n        BoldMagenta = Bold | Magenta,\n        Cyan = 0x24,\n        BoldCyan = Bold | Cyan,\n        White = 0x25,\n        BoldWhite = White | Bold,\n        Bold = 0x100\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ConsoleHandling/AnsiColorExtensions.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.txt file in the project root for more information.\n\nnamespace Microsoft.Repl.ConsoleHandling\n{\n    public static class AnsiColorExtensions\n    {\n        // For reference on these codes and values, see:\n        // https://en.wikipedia.org/wiki/ANSI_escape_code#Escape_sequences\n        private const string _ansiControlSequenceIntroducer = \"\\x1B[\";\n        private const string _ansiSgrCode = \"m\";\n        private static readonly string _ansiSgrDefaultForegroundColor = $\"{_ansiControlSequenceIntroducer}39{_ansiSgrCode}\";\n        private static readonly string _ansiSgrBold = $\"{_ansiControlSequenceIntroducer}1{_ansiSgrCode}\";\n\n        public static string Black(this string text)\n        {\n            return SetColorInternal(text, AllowedColors.Black);\n        }\n\n        public static string Red(this string text)\n        {\n            return SetColorInternal(text, AllowedColors.Red);\n        }\n        public static string Green(this string text)\n        {\n            return SetColorInternal(text, AllowedColors.Green);\n        }\n\n        public static string Yellow(this string text)\n        {\n            return SetColorInternal(text, AllowedColors.Yellow);\n        }\n\n        public static string Blue(this string text)\n        {\n            return SetColorInternal(text, AllowedColors.Blue);\n        }\n\n        public static string Magenta(this string text)\n        {\n            return SetColorInternal(text, AllowedColors.Magenta);\n        }\n\n        public static string Cyan(this string text)\n        {\n            return SetColorInternal(text, AllowedColors.Cyan);\n        }\n\n        public static string White(this string text)\n        {\n            return SetColorInternal(text, AllowedColors.White);\n        }\n\n        public static string Bold(this string text)\n        {\n            return $\"{_ansiSgrBold}{text}{_ansiSgrDefaultForegroundColor}\";\n        }\n\n        private static string SetColorInternal(string text, AllowedColors color)\n        {\n            int sgrParameter = (int)color;\n            return $\"{_ansiControlSequenceIntroducer}{sgrParameter}{_ansiSgrCode}{text}{_ansiSgrDefaultForegroundColor}\";\n        }\n\n        public static string SetColor(this string textToColor, AllowedColors color)\n        {\n            if (color.HasFlag(AllowedColors.Bold))\n            {\n                textToColor = textToColor.Bold();\n                color &= ~AllowedColors.Bold;\n            }\n\n            switch (color)\n            {\n                case AllowedColors.Black:\n                case AllowedColors.Red:\n                case AllowedColors.Green:\n                case AllowedColors.Yellow:\n                case AllowedColors.Blue:\n                case AllowedColors.Magenta:\n                case AllowedColors.Cyan:\n                case AllowedColors.White:\n                    return SetColorInternal(textToColor, color);\n                default:\n                    return textToColor;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ConsoleHandling/AnsiConsole.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.txt file in the project root for more information.\n\nusing System;\nusing System.IO;\n\nnamespace Microsoft.Repl.ConsoleHandling\n{\n    public class AnsiConsole\n    {\n        private AnsiConsole(TextWriter writer)\n        {\n            Writer = writer;\n\n            OriginalForegroundColor = Console.ForegroundColor;\n        }\n\n        private int _boldRecursion;\n\n        public static AnsiConsole GetOutput()\n        {\n            return new AnsiConsole(Console.Out);\n        }\n\n        public static AnsiConsole GetError()\n        {\n            return new AnsiConsole(Console.Error);\n        }\n\n        public TextWriter Writer { get; }\n\n        public ConsoleColor OriginalForegroundColor { get; }\n\n        private void SetColor(ConsoleColor color)\n        {\n            const int light = 0x08;\n            int c = (int)color;\n\n            Console.ForegroundColor =\n                c < 0 ? color :                                   // unknown, just use it\n                _boldRecursion > 0 ? (ConsoleColor)(c | light) :  // ensure color is light\n                (ConsoleColor)(c & ~light);                       // ensure color is dark\n        }\n\n        private void SetBold(bool bold)\n        {\n            _boldRecursion += bold ? 1 : -1;\n            if (_boldRecursion > 1 || (_boldRecursion == 1 && !bold))\n            {\n                return;\n            }\n\n            // switches on _boldRecursion to handle boldness\n            SetColor(Console.ForegroundColor);\n        }\n\n        public void WriteLine(string message)\n        {\n            Write(message);\n            Writer.WriteLine();\n        }\n\n        public void Write(char message)\n        {\n            Writer.Write(message);\n        }\n\n        public void Write(string message)\n        {\n            if (message is null)\n            {\n                return;\n            }\n\n            var escapeScan = 0;\n            for (; ; )\n            {\n                var escapeIndex = message.IndexOf(\"\\x1b[\", escapeScan, StringComparison.Ordinal);\n                if (escapeIndex == -1)\n                {\n                    var text = message.Substring(escapeScan);\n                    Writer.Write(text);\n                    break;\n                }\n                else\n                {\n                    var startIndex = escapeIndex + 2;\n                    var endIndex = startIndex;\n                    while (endIndex != message.Length &&\n                        message[endIndex] >= 0x20 &&\n                        message[endIndex] <= 0x3f)\n                    {\n                        endIndex += 1;\n                    }\n\n                    var text = message.Substring(escapeScan, escapeIndex - escapeScan);\n                    Writer.Write(text);\n                    if (endIndex == message.Length)\n                    {\n                        break;\n                    }\n\n                    switch (message[endIndex])\n                    {\n                        case 'm':\n                            if (int.TryParse(message.Substring(startIndex, endIndex - startIndex), out int value))\n                            {\n                                switch (value)\n                                {\n                                    case 1:\n                                        SetBold(true);\n                                        break;\n                                    case 22:\n                                        SetBold(false);\n                                        break;\n                                    case 30:\n                                        SetColor(ConsoleColor.Black);\n                                        break;\n                                    case 31:\n                                        SetColor(ConsoleColor.Red);\n                                        break;\n                                    case 32:\n                                        SetColor(ConsoleColor.Green);\n                                        break;\n                                    case 33:\n                                        SetColor(ConsoleColor.Yellow);\n                                        break;\n                                    case 34:\n                                        SetColor(ConsoleColor.Blue);\n                                        break;\n                                    case 35:\n                                        SetColor(ConsoleColor.Magenta);\n                                        break;\n                                    case 36:\n                                        SetColor(ConsoleColor.Cyan);\n                                        break;\n                                    case 37:\n                                        SetColor(ConsoleColor.Gray);\n                                        break;\n                                    case 39:\n                                        Console.ForegroundColor = OriginalForegroundColor;\n                                        break;\n                                }\n                            }\n                            break;\n                    }\n\n                    escapeScan = endIndex + 1;\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ConsoleHandling/ConsoleManager.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\nnamespace Microsoft.Repl.ConsoleHandling\n{\n    public class ConsoleManager : IConsoleManager\n    {\n        private readonly List<Action> _breakHandlers = new List<Action>();\n\n        public Point Caret => new Point(Console.CursorLeft, Console.CursorTop);\n\n        public bool IsKeyAvailable => Console.KeyAvailable;\n\n        public bool IsCaretVisible\n        {\n            get => Reporter.Output.IsCaretVisible;\n            set => Reporter.Output.IsCaretVisible = value;\n        }\n\n        public ConsoleManager()\n        {\n            Error = new Writable(Reporter.Error);\n            Console.CancelKeyPress += OnCancelKeyPress;\n        }\n\n        public void Clear()\n        {\n            Console.Clear();\n        }\n\n        public void MoveCaret(int positions)\n        {\n            if (positions == 0)\n            {\n                return;\n            }\n\n            int bufferWidth = Console.BufferWidth;\n            int cursorTop = Console.CursorTop;\n            int cursorLeft = Console.CursorLeft;\n\n            while (positions < 0)\n            {\n                if (-positions > bufferWidth)\n                {\n                    if (cursorTop == 0)\n                    {\n                        cursorLeft = 0;\n                        positions = 0;\n                    }\n                    else\n                    {\n                        positions += bufferWidth;\n                        --cursorTop;\n                    }\n                }\n                else\n                {\n                    int remaining = cursorLeft + positions;\n\n                    if (remaining >= 0)\n                    {\n                        cursorLeft = remaining;\n                    }\n                    else if (cursorTop == 0)\n                    {\n                        cursorLeft = 0;\n                    }\n                    else\n                    {\n                        --cursorTop;\n                        cursorLeft = bufferWidth + remaining;\n                    }\n\n                    positions = 0;\n                }\n            }\n\n            while (positions > 0)\n            {\n                if (positions > bufferWidth)\n                {\n                    positions -= bufferWidth;\n                    ++cursorTop;\n                }\n                else\n                {\n                    int spaceLeftOnLine = bufferWidth - cursorLeft - 1;\n                    if (positions > spaceLeftOnLine)\n                    {\n                        ++cursorTop;\n                        cursorLeft = positions - spaceLeftOnLine - 1;\n                    }\n                    else\n                    {\n                        cursorLeft += positions;\n                    }\n\n                    positions = 0;\n                }\n            }\n\n            Console.SetCursorPosition(cursorLeft, cursorTop);\n        }\n\n        public ConsoleKeyInfo ReadKey(CancellationToken cancellationToken)\n        {\n            while (!Console.KeyAvailable && !cancellationToken.IsCancellationRequested)\n            {\n                Thread.Sleep(2);\n            }\n\n            if (cancellationToken.IsCancellationRequested)\n            {\n                return default;\n            }\n            else\n            {\n                return Console.ReadKey(true);\n            }\n        }\n\n        public void Write(char c)\n        {\n            Reporter.Output.Write(c);\n        }\n\n        public void Write(string s)\n        {\n            Reporter.Output.Write(s);\n        }\n\n        public void WriteLine()\n        {\n            Reporter.Output.WriteLine();\n        }\n\n        public void WriteLine(string s)\n        {\n            if (s is null)\n            {\n                return;\n            }\n\n            Reporter.Output.WriteLine(s);\n        }\n\n        public IDisposable AddBreakHandler(Action onBreak)\n        {\n            Disposable result = new Disposable(() => ReleaseBreakHandler(onBreak));\n            _breakHandlers.Add(onBreak);\n            return result;\n        }\n\n        private void OnCancelKeyPress(object sender, ConsoleCancelEventArgs e)\n        {\n            e.Cancel = true;\n            Action handler = _breakHandlers.LastOrDefault();\n            handler?.Invoke();\n        }\n\n        private void ReleaseBreakHandler(Action handler)\n        {\n            _breakHandlers.Remove(handler);\n        }\n\n        public IWritable Error { get; }\n\n        public bool AllowOutputRedirection => false;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ConsoleHandling/IConsoleManager.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.txt file in the project root for more information.\n\nusing System;\nusing System.Threading;\n\nnamespace Microsoft.Repl.ConsoleHandling\n{\n    public interface IConsoleManager : IWritable\n    {\n        Point Caret { get; }\n\n#pragma warning disable CA1716 // Identifiers should not match keywords\n        IWritable Error { get; }\n#pragma warning restore CA1716 // Identifiers should not match keywords\n\n        bool IsKeyAvailable { get; }\n\n        void Clear();\n\n        void MoveCaret(int positions);\n\n        ConsoleKeyInfo ReadKey(CancellationToken cancellationToken);\n\n        IDisposable AddBreakHandler(Action onBreak);\n\n        bool AllowOutputRedirection { get; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ConsoleHandling/IWritable.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.txt file in the project root for more information.\n\nnamespace Microsoft.Repl.ConsoleHandling\n{\n    public interface IWritable\n    {\n        void Write(char c);\n\n        void Write(string s);\n\n        void WriteLine();\n\n        void WriteLine(string s);\n\n        bool IsCaretVisible { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ConsoleHandling/Point.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.txt file in the project root for more information.\n\nusing System;\n\nnamespace Microsoft.Repl.ConsoleHandling\n{\n    public struct Point : IEquatable<Point>\n    {\n        public int X { get; }\n\n        public int Y { get; }\n\n        public Point(int x, int y)\n        {\n            X = x;\n            Y = y;\n        }\n\n        public override bool Equals(object obj)\n        {\n            if (obj is null)\n            {\n                return false;\n            }\n\n            if (!(obj is Point other))\n            {\n                return false;\n            }\n            else\n            {\n                return Equals(other);\n            }\n        }\n\n        public override int GetHashCode()\n        {\n            int hash = 27;\n            hash = (13 * hash) + X.GetHashCode();\n            hash = (13 * hash) + Y.GetHashCode();\n            return hash;\n        }\n\n        public static bool operator ==(Point left, Point right)\n        {\n            return left.Equals(right);\n        }\n\n        public static bool operator !=(Point left, Point right)\n        {\n            return !(left == right);\n        }\n\n        public bool Equals(Point other)\n        {\n            return X == other.X && Y == other.Y;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ConsoleHandling/Reporter.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.txt file in the project root for more information.\n\nusing System;\n\nnamespace Microsoft.Repl.ConsoleHandling\n{\n    public class Reporter : IWritable\n    {\n        private static readonly Reporter NullReporter = new Reporter(null);\n        private static readonly object Sync = new object();\n\n        private readonly AnsiConsole _console;\n\n        static Reporter()\n        {\n            Reset();\n        }\n\n        private Reporter(AnsiConsole console)\n        {\n            _console = console;\n        }\n\n        public static Reporter Output { get; private set; }\n        public static Reporter Error { get; private set; }\n        public static Reporter Verbose { get; private set; }\n\n        /// <summary>\n        /// Resets the Reporters to write to the current Console Out/Error.\n        /// </summary>\n        public static void Reset()\n        {\n            lock (Sync)\n            {\n                Output = new Reporter(AnsiConsole.GetOutput());\n                Error = new Reporter(AnsiConsole.GetError());\n                Verbose = IsVerbose ?\n                    new Reporter(AnsiConsole.GetOutput()) :\n                    NullReporter;\n            }\n        }\n\n        public void WriteLine(string s)\n        {\n            if (s is null)\n            {\n                return;\n            }\n\n            lock (Sync)\n            {\n                if (ShouldPassAnsiCodesThrough)\n                {\n                    _console?.Writer?.WriteLine(s);\n                }\n                else\n                {\n                    _console?.WriteLine(s);\n                }\n            }\n        }\n\n        public void WriteLine()\n        {\n            lock (Sync)\n            {\n                _console?.Writer?.WriteLine();\n            }\n        }\n\n        public void Write(char c)\n        {\n            lock (Sync)\n            {\n                if (ShouldPassAnsiCodesThrough)\n                {\n                    _console?.Writer?.Write(c);\n                }\n                else\n                {\n                    _console?.Write(c);\n                }\n            }\n        }\n\n        public void Write(string s)\n        {\n            lock (Sync)\n            {\n                if (ShouldPassAnsiCodesThrough)\n                {\n                    _console?.Writer?.Write(s);\n                }\n                else\n                {\n                    _console?.Write(s);\n                }\n            }\n        }\n\n        private static bool IsVerbose => bool.TryParse(Environment.GetEnvironmentVariable(\"DOTNET_CLI_CONTEXT_VERBOSE\") ?? \"false\", out bool value) && value;\n\n        private static bool ShouldPassAnsiCodesThrough => bool.TryParse(Environment.GetEnvironmentVariable(\"DOTNET_CLI_CONTEXT_ANSI_PASS_THRU\") ?? \"false\", out bool value) && value;\n\n        private bool _isCaretVisible = true;\n\n        public bool IsCaretVisible\n        {\n            get => _isCaretVisible;\n            set\n            {\n                Console.CursorVisible = value;\n                _isCaretVisible = value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ConsoleHandling/Writable.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.txt file in the project root for more information.\n\nnamespace Microsoft.Repl.ConsoleHandling\n{\n    internal class Writable : IWritable\n    {\n        private readonly Reporter _reporter;\n\n        public Writable(Reporter reporter)\n        {\n            _reporter = reporter;\n        }\n\n        public bool IsCaretVisible\n        {\n            get => _reporter.IsCaretVisible;\n            set => _reporter.IsCaretVisible = value;\n        }\n\n        public void Write(char c)\n        {\n            _reporter.Write(c);\n        }\n\n        public void Write(string s)\n        {\n            _reporter.Write(s);\n        }\n\n        public void WriteLine()\n        {\n            _reporter.WriteLine();\n        }\n\n        public void WriteLine(string s)\n        {\n            _reporter.WriteLine(s);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Disposable.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.txt file in the project root for more information.\n\nusing System;\n\nnamespace Microsoft.Repl\n{\n    public class Disposable : IDisposable\n    {\n        private Action _onDispose;\n\n        public Disposable(Action onDispose)\n        {\n            _onDispose = onDispose;\n        }\n        public virtual void Dispose()\n        {\n            _onDispose?.Invoke();\n            _onDispose = null;\n            GC.SuppressFinalize(this);\n        }\n    }\n\n    public class Disposable<T> : Disposable\n        where T : class\n    {\n        public Disposable(T value, Action onDispose)\n            : base (onDispose)\n        {\n            Value = value;\n        }\n\n        public T Value { get; private set; }\n\n        public override void Dispose()\n        {\n            if (Value is IDisposable d)\n            {\n                d.Dispose();\n                Value = null;\n            }\n\n            base.Dispose();\n            GC.SuppressFinalize(this);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/IShellState.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Input;\nusing Microsoft.Repl.Suggestions;\n\nnamespace Microsoft.Repl\n{\n    public interface IShellState\n    {\n        IInputManager InputManager { get; }\n\n        ICommandHistory CommandHistory { get; }\n\n        IConsoleManager ConsoleManager { get; }\n\n        ICommandDispatcher CommandDispatcher { get; }\n\n        ISuggestionManager SuggestionManager { get; }\n\n        bool IsExiting { get; set; }\n\n        void MoveCarets(int positions);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Input/AsyncKeyPressHandler.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.txt file in the project root for more information.\n\nusing System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Microsoft.Repl.Input\n{\n    public delegate Task AsyncKeyPressHandler(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken);\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Input/IInputManager.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.txt file in the project root for more information.\n\nusing System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Microsoft.Repl.Input\n{\n    public interface IInputManager\n    {\n        bool IsOverwriteMode { get; set; }\n\n        int CaretPosition { get; }\n\n        IInputManager RegisterKeyHandler(ConsoleKey key, AsyncKeyPressHandler handler);\n\n        IInputManager RegisterKeyHandler(ConsoleKey key, ConsoleModifiers modifiers, AsyncKeyPressHandler handler);\n\n        void ResetInput();\n\n        Task StartAsync(IShellState state, CancellationToken cancellationToken);\n\n        void SetInput(IShellState state, string input);\n\n        string GetCurrentBuffer();\n\n        void RemovePreviousCharacter(IShellState state);\n\n        void RemoveCurrentCharacter(IShellState state);\n\n        void Clear(IShellState state);\n\n        void MoveCaret(int positions);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Input/InputManager.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Microsoft.Repl.Input\n{\n    public class InputManager : IInputManager\n    {\n        private readonly Dictionary<ConsoleKey, Dictionary<ConsoleModifiers, AsyncKeyPressHandler>> _handlers = new Dictionary<ConsoleKey, Dictionary<ConsoleModifiers, AsyncKeyPressHandler>>();\n        private readonly List<char> _inputBuffer = new List<char>();\n\n        public InputManager() { }\n\n        /// <summary>\n        /// For testing purposes only\n        /// </summary>\n        internal InputManager(string initialInput, int initialPosition)\n        {\n            _inputBuffer.AddRange(initialInput);\n            CaretPosition = initialPosition;\n        }\n\n\n        public bool IsOverwriteMode { get; set; }\n\n        public int CaretPosition { get; private set; }\n\n        public void MoveCaret(int positions)\n        {\n            if (CaretPosition + positions < 0)\n            {\n                CaretPosition = 0;\n            }\n            else if (CaretPosition + positions > _inputBuffer.Count)\n            {\n                CaretPosition = _inputBuffer.Count;\n            }\n            else\n            {\n                CaretPosition += positions;\n            }\n        }\n\n        public void Clear(IShellState state)\n        {\n            SetInput(state, string.Empty);\n        }\n\n        public string GetCurrentBuffer()\n        {\n            return _inputBuffer.Stringify();\n        }\n\n        public IInputManager RegisterKeyHandler(ConsoleKey key, AsyncKeyPressHandler handler)\n        {\n            if (!_handlers.TryGetValue(key, out Dictionary<ConsoleModifiers, AsyncKeyPressHandler> handlers))\n            {\n                _handlers[key] = handlers = new Dictionary<ConsoleModifiers, AsyncKeyPressHandler>();\n            }\n\n            if (handler == null)\n            {\n                handlers.Remove(default);\n            }\n            else\n            {\n                handlers[default] = handler;\n            }\n\n            return this;\n        }\n\n        public IInputManager RegisterKeyHandler(ConsoleKey key, ConsoleModifiers modifiers, AsyncKeyPressHandler handler)\n        {\n            if (!_handlers.TryGetValue(key, out Dictionary<ConsoleModifiers, AsyncKeyPressHandler> handlers))\n            {\n                _handlers[key] = handlers = new Dictionary<ConsoleModifiers, AsyncKeyPressHandler>();\n            }\n\n            if (handler == null)\n            {\n                handlers.Remove(modifiers);\n            }\n            else\n            {\n                handlers[modifiers] = handler;\n            }\n\n            return this;\n        }\n\n        public void RemoveCurrentCharacter(IShellState state)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            int caret = CaretPosition;\n            if (caret == _inputBuffer.Count)\n            {\n                return;\n            }\n\n            List<char> update = _inputBuffer.ToList();\n            update.RemoveAt(caret);\n            state.ConsoleManager.IsCaretVisible = false;\n            SetInput(state, update);\n            state.MoveCarets(caret - CaretPosition);\n            state.ConsoleManager.IsCaretVisible = true;\n        }\n\n        public void RemovePreviousCharacter(IShellState state)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            int caret = CaretPosition;\n            if (caret == 0)\n            {\n                return;\n            }\n\n            List<char> update = _inputBuffer.ToList();\n            update.RemoveAt(caret - 1);\n            state.ConsoleManager.IsCaretVisible = false;\n            SetInput(state, update);\n            state.MoveCarets(caret - CaretPosition - 1);\n            state.ConsoleManager.IsCaretVisible = true;\n        }\n\n        public void SetInput(IShellState state, string input)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            input = input ?? throw new ArgumentNullException(nameof(input));\n\n            SetInput(state, input.ToCharArray());\n        }\n\n        public void ResetInput()\n        {\n            _inputBuffer.Clear();\n            CaretPosition = 0;\n        }\n\n        private string _ttyState;\n\n        private void StashEchoState()\n        {\n            string sttyFlags = null;\n            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))\n            {\n                _ttyState = GetTtyState();\n                sttyFlags = \"gfmt1:erase=08:werase=08 -echo -icanon\";\n            }\n            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))\n            {\n                _ttyState = GetTtyState();\n                sttyFlags = \"erase 0x08 werase 0x08 -echo -icanon\";\n            }\n\n            if (!string.IsNullOrEmpty(sttyFlags))\n            {\n                ProcessStartInfo psi = new ProcessStartInfo(\"stty\", sttyFlags);\n                Process p = Process.Start(psi);\n                p?.WaitForExit();\n            }\n        }\n\n        private static string GetTtyState()\n        {\n            ProcessStartInfo psi = new ProcessStartInfo(\"stty\", \"-g\")\n            {\n                RedirectStandardOutput = true\n            };\n            Process p = Process.Start(psi);\n            p?.WaitForExit();\n            string result = p?.StandardOutput.ReadToEnd().Trim();\n            return result;\n        }\n\n        private void RestoreTtyState()\n        {\n            if (!string.IsNullOrEmpty(_ttyState))\n            {\n                ProcessStartInfo psi = new ProcessStartInfo(\"stty\", _ttyState);\n                Process p = Process.Start(psi);\n                p?.WaitForExit();\n            }\n        }\n\n        private void SetInput(IShellState state, IReadOnlyList<char> input)\n        {\n            bool oldCaretVisibility = state.ConsoleManager.IsCaretVisible;\n            state.ConsoleManager.IsCaretVisible = false;\n            int lastCommonPosition = 0;\n\n            for (; lastCommonPosition < input.Count && lastCommonPosition < _inputBuffer.Count && _inputBuffer[lastCommonPosition] == input[lastCommonPosition]; ++lastCommonPosition)\n            {\n            }\n\n            state.ConsoleManager.MoveCaret(-CaretPosition + lastCommonPosition);\n            string str = new string(input.Skip(lastCommonPosition).ToArray());\n            int trailing = _inputBuffer.Count - input.Count;\n\n            if (trailing > 0)\n            {\n                str = str.PadRight(trailing + str.Length);\n            }\n\n            state.ConsoleManager.Write(str);\n\n            _inputBuffer.Clear();\n            _inputBuffer.AddRange(input);\n\n            if (trailing > 0)\n            {\n                state.ConsoleManager.MoveCaret(-trailing);\n            }\n\n            CaretPosition = _inputBuffer.Count;\n\n            if (oldCaretVisibility)\n            {\n                state.ConsoleManager.IsCaretVisible = true;\n            }\n        }\n\n        public async Task StartAsync(IShellState state, CancellationToken cancellationToken)\n        {\n            _ = state ?? throw new ArgumentNullException(nameof(state));\n\n            StashEchoState();\n\n            try\n            {\n                List<ConsoleKeyInfo> presses = null;\n                while (!state.IsExiting && !cancellationToken.IsCancellationRequested)\n                {\n                    ConsoleKeyInfo keyPress = state.ConsoleManager.ReadKey(cancellationToken);\n\n                    if (_handlers.TryGetValue(keyPress.Key, out Dictionary<ConsoleModifiers, AsyncKeyPressHandler> handlerLookup) && handlerLookup.TryGetValue(keyPress.Modifiers, out AsyncKeyPressHandler handler))\n                    {\n                        using (CancellationTokenSource source = new CancellationTokenSource())\n                        using (state.ConsoleManager.AddBreakHandler(() => source.Cancel()))\n                        {\n                            if (presses != null)\n                            {\n                                FlushInput(state, ref presses);\n                            }\n\n                            await handler(keyPress, state, source.Token).ConfigureAwait(false);\n                        }\n                    }\n                    else if (!string.IsNullOrEmpty(_ttyState) && keyPress.Modifiers == ConsoleModifiers.Control)\n                    {\n                        if (presses != null)\n                        {\n                            FlushInput(state, ref presses);\n                        }\n\n                        //TODO: Verify on a mac whether these are still needed\n                        if (keyPress.Key == ConsoleKey.A)\n                        {\n                            state.ConsoleManager.MoveCaret(-CaretPosition);\n                            CaretPosition = 0;\n                        }\n                        else if (keyPress.Key == ConsoleKey.E)\n                        {\n                            state.ConsoleManager.MoveCaret(_inputBuffer.Count - CaretPosition);\n                            CaretPosition = _inputBuffer.Count;\n                        }\n                    }\n                    //TODO: Register these like regular commands\n                    else if (!string.IsNullOrEmpty(_ttyState) && keyPress.Modifiers == ConsoleModifiers.Alt)\n                    {\n                        if (presses != null)\n                        {\n                            FlushInput(state, ref presses);\n                        }\n\n                        //Move back a word\n                        if (keyPress.Key == ConsoleKey.B)\n                        {\n                            int i = CaretPosition - 1;\n\n                            if (i < 0)\n                            {\n                                continue;\n                            }\n\n                            bool letterMode = char.IsLetterOrDigit(_inputBuffer[i]);\n\n                            for (; i > 0 && (char.IsLetterOrDigit(_inputBuffer[i]) == letterMode); --i)\n                            {\n                            }\n\n                            if (letterMode && i > 0)\n                            {\n                                ++i;\n                            }\n\n                            if (i > -1)\n                            {\n                                state.ConsoleManager.MoveCaret(i - CaretPosition);\n                                CaretPosition = i;\n                            }\n                        }\n                        //Move forward a word\n                        else if (keyPress.Key == ConsoleKey.F)\n                        {\n                            int i = CaretPosition + 1;\n\n                            if (i >= _inputBuffer.Count)\n                            {\n                                continue;\n                            }\n\n                            bool letterMode = char.IsLetterOrDigit(_inputBuffer[i]);\n\n                            for (; i < _inputBuffer.Count && (char.IsLetterOrDigit(_inputBuffer[i]) == letterMode); ++i)\n                            {\n                            }\n\n                            if (letterMode && i < _inputBuffer.Count - 1 && i > 0)\n                            {\n                                --i;\n                            }\n\n                            state.ConsoleManager.MoveCaret(i - CaretPosition);\n                            CaretPosition = i;\n                        }\n                    }\n                    else\n                    {\n                        // If we got here, we've processed all handlers we know for\n                        // key combinations. So anything else should have a valid\n                        // character or be the null character. If its the latter,\n                        // we just want to ignore it.\n                        if (keyPress.KeyChar == '\\0')\n                        {\n                            continue;\n                        }\n\n                        if (state.ConsoleManager.IsKeyAvailable)\n                        {\n                            if (presses == null)\n                            {\n                                presses = new List<ConsoleKeyInfo>();\n                            }\n\n                            presses.Add(keyPress);\n                            continue;\n                        }\n\n                        if (presses != null)\n                        {\n                            presses.Add(keyPress);\n                            FlushInput(state, ref presses);\n                            continue;\n                        }\n\n                        if (CaretPosition == _inputBuffer.Count)\n                        {\n                            _inputBuffer.Add(keyPress.KeyChar);\n                            state.ConsoleManager.Write(keyPress.KeyChar);\n                            MoveCaret(1);\n                        }\n                        else if (IsOverwriteMode)\n                        {\n                            _inputBuffer[CaretPosition] = keyPress.KeyChar;\n                            state.ConsoleManager.Write(keyPress.KeyChar);\n                            MoveCaret(1);\n                        }\n                        else\n                        {\n                            state.ConsoleManager.IsCaretVisible = false;\n                            _inputBuffer.Insert(CaretPosition, keyPress.KeyChar);\n                            string s = new string(_inputBuffer.ToArray(), CaretPosition, _inputBuffer.Count - CaretPosition);\n                            state.ConsoleManager.Write(s);\n                            // Since we're \"inserting\", move the console cursor back by one fewer\n                            // than the length of the string just written to the console\n                            state.ConsoleManager.MoveCaret(-1 * (s.Length - 1));\n                            state.ConsoleManager.IsCaretVisible = true;\n                            MoveCaret(1);\n                        }\n                    }\n                }\n            }\n            finally\n            {\n                RestoreTtyState();\n            }\n        }\n\n        private void FlushInput(IShellState state, ref List<ConsoleKeyInfo> presses)\n        {\n            string str = new string(presses.Select(x => x.KeyChar).ToArray());\n\n            if (CaretPosition == _inputBuffer.Count)\n            {\n                _inputBuffer.AddRange(str);\n                state.ConsoleManager.Write(str);\n            }\n            else if (IsOverwriteMode)\n            {\n                for (int i = 0; i < str.Length; ++i)\n                {\n                    if (CaretPosition + i < _inputBuffer.Count)\n                    {\n                        _inputBuffer[CaretPosition + i] = str[i];\n                    }\n                    else\n                    {\n                        _inputBuffer.AddRange(str.Skip(i));\n                        break;\n                    }\n                }\n\n                state.ConsoleManager.Write(str);\n            }\n            else\n            {\n                state.ConsoleManager.IsCaretVisible = false;\n                _inputBuffer.InsertRange(CaretPosition, str);\n                int currentCaretPosition = CaretPosition;\n                string s = new string(_inputBuffer.ToArray(), CaretPosition, _inputBuffer.Count - CaretPosition);\n                state.ConsoleManager.Write(s);\n                state.ConsoleManager.MoveCaret(currentCaretPosition - CaretPosition + str.Length);\n                state.ConsoleManager.IsCaretVisible = true;\n            }\n            MoveCaret(str.Length);\n\n            presses = null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Input/KeyHandlers.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.txt file in the project root for more information.\n\nusing System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.Repl.Input\n{\n    public static class KeyHandlers\n    {\n        public static void RegisterDefaultKeyHandlers(IInputManager inputManager)\n        {\n            inputManager = inputManager ?? throw new ArgumentNullException(nameof(inputManager));\n\n            //Navigation in line\n            inputManager.RegisterKeyHandler(ConsoleKey.LeftArrow, LeftArrow);\n            inputManager.RegisterKeyHandler(ConsoleKey.LeftArrow, ConsoleModifiers.Control, LeftArrow);\n            inputManager.RegisterKeyHandler(ConsoleKey.RightArrow, RightArrow);\n            inputManager.RegisterKeyHandler(ConsoleKey.RightArrow, ConsoleModifiers.Control, RightArrow);\n            inputManager.RegisterKeyHandler(ConsoleKey.Home, Home);\n            inputManager.RegisterKeyHandler(ConsoleKey.A, ConsoleModifiers.Control, Home);\n            inputManager.RegisterKeyHandler(ConsoleKey.End, End);\n            inputManager.RegisterKeyHandler(ConsoleKey.E, ConsoleModifiers.Control, End);\n\n            //Command history\n            inputManager.RegisterKeyHandler(ConsoleKey.UpArrow, UpArrow);\n            inputManager.RegisterKeyHandler(ConsoleKey.DownArrow, DownArrow);\n\n            //Completion\n            inputManager.RegisterKeyHandler(ConsoleKey.Tab, Tab);\n            inputManager.RegisterKeyHandler(ConsoleKey.Tab, ConsoleModifiers.Shift, Tab);\n\n            //Input manipulation\n            inputManager.RegisterKeyHandler(ConsoleKey.Escape, Escape);\n            inputManager.RegisterKeyHandler(ConsoleKey.U, ConsoleModifiers.Control, Escape);\n            inputManager.RegisterKeyHandler(ConsoleKey.Delete, Delete);\n            inputManager.RegisterKeyHandler(ConsoleKey.Backspace, Backspace);\n\n            //Insert/Overwrite mode\n            inputManager.RegisterKeyHandler(ConsoleKey.Insert, Insert);\n\n            //Execute command\n            inputManager.RegisterKeyHandler(ConsoleKey.Enter, Enter);\n\n            //Map non-printable keys that aren't handled by default\n            inputManager.RegisterKeyHandler(ConsoleKey.F1, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F2, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F3, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F4, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F5, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F6, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F7, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F8, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F9, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F10, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F11, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F12, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F13, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F14, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F15, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F16, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F17, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F18, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F19, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F20, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F21, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F22, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F23, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.F24, Unhandled);\n\n            inputManager.RegisterKeyHandler(ConsoleKey.Clear, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.Execute, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.Help, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.PageDown, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.PageUp, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.Pause, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.Print, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.PrintScreen, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.Select, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.Separator, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.Sleep, Unhandled);\n\n            inputManager.RegisterKeyHandler(ConsoleKey.LeftWindows, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.RightWindows, Unhandled);\n            inputManager.RegisterKeyHandler(ConsoleKey.Applications, Unhandled);\n        }\n\n        private static Task End(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state.MoveCarets(state.InputManager.GetCurrentBuffer().Length - state.InputManager.CaretPosition);\n            return Task.CompletedTask;\n        }\n\n        public static Task Home(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            state.MoveCarets(-state.InputManager.CaretPosition);\n            return Task.CompletedTask;\n        }\n\n        public static Task LeftArrow(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            if (state.InputManager.CaretPosition > 0)\n            {\n                if (!keyInfo.Modifiers.HasFlag(ConsoleModifiers.Control))\n                {\n                    state.MoveCarets(-1);\n                }\n                else\n                {\n                    string line = state.InputManager.GetCurrentBuffer();\n                    ICoreParseResult parseResult = state.CommandDispatcher.Parser.Parse(line, state.InputManager.CaretPosition);\n                    int targetSection = parseResult.SelectedSection - (parseResult.CaretPositionWithinSelectedSection > 0 ? 0 : 1);\n\n                    if (targetSection < 0)\n                    {\n                        targetSection = 0;\n                    }\n\n                    int desiredPosition = parseResult.SectionStartLookup[targetSection];\n                    state.MoveCarets(desiredPosition - state.InputManager.CaretPosition);\n                }\n            }\n\n            return Task.CompletedTask;\n        }\n\n        public static Task RightArrow(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            string line = state.InputManager.GetCurrentBuffer();\n\n            if (state.InputManager.CaretPosition < line.Length)\n            {\n                if (!keyInfo.Modifiers.HasFlag(ConsoleModifiers.Control))\n                {\n                    state.MoveCarets(1);\n                }\n                else\n                {\n                    ICoreParseResult parseResult = state.CommandDispatcher.Parser.Parse(line, state.InputManager.CaretPosition);\n                    int targetSection = parseResult.SelectedSection + 1;\n\n                    if (targetSection >= parseResult.Sections.Count)\n                    {\n                        state.MoveCarets(line.Length - state.InputManager.CaretPosition);\n                    }\n                    else\n                    {\n                        int desiredPosition = parseResult.SectionStartLookup[targetSection];\n                        state.MoveCarets(desiredPosition - state.InputManager.CaretPosition);\n                    }\n                }\n            }\n\n            return Task.CompletedTask;\n        }\n\n        public static Task UpArrow(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            string line = state.CommandHistory.GetPreviousCommand();\n            state.InputManager.SetInput(state, line);\n            return Task.CompletedTask;\n        }\n\n        public static Task DownArrow(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            string line = state.CommandHistory.GetNextCommand();\n            state.InputManager.SetInput(state, line);\n            return Task.CompletedTask;\n        }\n\n        public static Task Enter(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            return state.CommandDispatcher.ExecuteCommandAsync(state, cancellationToken);\n        }\n\n        public static Task Backspace(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            state.InputManager.RemovePreviousCharacter(state);\n            return Task.CompletedTask;\n        }\n\n        public static Task Unhandled(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            return Task.CompletedTask;\n        }\n\n        public static Task Escape(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            state.InputManager.SetInput(state, string.Empty);\n            return Task.CompletedTask;\n        }\n\n        public static Task Tab(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            if (keyInfo.Modifiers.HasFlag(ConsoleModifiers.Shift))\n            {\n                state.SuggestionManager.PreviousSuggestion(state);\n            }\n            else\n            {\n                state.SuggestionManager.NextSuggestion(state);\n            }\n\n            return Task.CompletedTask;\n        }\n\n        public static Task Delete(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            state.InputManager.RemoveCurrentCharacter(state);\n            return Task.CompletedTask;\n        }\n\n        public static Task Insert(ConsoleKeyInfo keyInfo, IShellState state, CancellationToken cancellationToken)\n        {\n            state = state ?? throw new ArgumentNullException(nameof(state));\n\n            state.InputManager.IsOverwriteMode = !state.InputManager.IsOverwriteMode;\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Microsoft.Repl.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net8.0</TargetFramework>\n    <Description>A framework for creating REPLs in .NET Standard.</Description>\n    <PackageTags>dotnet;repl</PackageTags>\n    <PackageId>Microsoft.Repl</PackageId>\n\n    <IsPackable>true</IsPackable>\n    <IsShipping>false</IsShipping>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"System.Diagnostics.Process\" />\n    <PackageReference Include=\"System.Threading.Thread\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Compile Update=\"Resources\\Strings.Designer.cs\">\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Strings.resx</DependentUpon>\n    </Compile>\n  </ItemGroup>\n\n  <ItemGroup>\n    <EmbeddedResource Update=\"Resources\\Strings.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Strings.Designer.cs</LastGenOutput>\n    </EmbeddedResource>\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Microsoft.Repl/Parsing/CoreParseResult.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Microsoft.Repl.Parsing\n{\n    public class CoreParseResult : ICoreParseResult\n    {\n        public CoreParseResult(int caretPositionWithinCommandText, int caretPositionWithinSelectedSection, string commandText, IReadOnlyList<string> sections, int selectedSection, IReadOnlyDictionary<int, int> sectionStartLookup, HashSet<int> quotedSections)\n        {\n            CaretPositionWithinCommandText = caretPositionWithinCommandText;\n            CaretPositionWithinSelectedSection = caretPositionWithinSelectedSection;\n            CommandText = commandText;\n            Sections = sections;\n            SelectedSection = selectedSection;\n            SectionStartLookup = sectionStartLookup;\n            _quotedSections = quotedSections;\n        }\n\n        public int CaretPositionWithinCommandText { get; }\n\n        public int CaretPositionWithinSelectedSection { get; }\n\n        public string CommandText { get; }\n\n        public IReadOnlyList<string> Sections { get; }\n\n        public int SelectedSection { get; }\n\n        public IReadOnlyDictionary<int, int> SectionStartLookup { get; }\n\n        private readonly HashSet<int> _quotedSections;\n\n        public bool IsQuotedSection(int index)\n        {\n            return _quotedSections.Contains(index);\n        }\n\n        public virtual ICoreParseResult Slice(int numberOfLeadingSectionsToRemove)\n        {\n            if (numberOfLeadingSectionsToRemove == 0)\n            {\n                return this;\n            }\n\n            if (numberOfLeadingSectionsToRemove >= Sections.Count)\n            {\n                return new CoreParseResult(0, 0, string.Empty, new[] { string.Empty }, 0, new Dictionary<int, int> { { 0, 0 } }, new HashSet<int>());\n            }\n\n            string commandText = CommandText.Substring(SectionStartLookup[numberOfLeadingSectionsToRemove]);\n            int caretPositionWithinCommandText = CaretPositionWithinCommandText - SectionStartLookup[numberOfLeadingSectionsToRemove];\n\n            if (caretPositionWithinCommandText < 0)\n            {\n                caretPositionWithinCommandText = 0;\n            }\n\n            Dictionary<int, int> sectionStartLookup = new Dictionary<int, int>();\n            List<string> sections = new List<string>();\n            for (int i = 0; i < Sections.Count - numberOfLeadingSectionsToRemove; ++i)\n            {\n                sectionStartLookup[i] = SectionStartLookup[numberOfLeadingSectionsToRemove + i] - SectionStartLookup[numberOfLeadingSectionsToRemove];\n                sections.Add(Sections[numberOfLeadingSectionsToRemove + i]);\n            }\n\n            int selectedSection = SelectedSection - numberOfLeadingSectionsToRemove;\n\n            if (selectedSection < 0)\n            {\n                selectedSection = 0;\n            }\n\n            HashSet<int> quotedSections = new HashSet<int>(_quotedSections.Where(x => x > 0).Select(x => x - 1));\n            return new CoreParseResult(caretPositionWithinCommandText, CaretPositionWithinSelectedSection, commandText, sections, selectedSection, sectionStartLookup, quotedSections);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Parsing/CoreParseResultExtensions.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace Microsoft.Repl.Parsing\n{\n    public static class CoreParseResultExtensions\n    {\n        public static bool ContainsExactly(this ICoreParseResult parseResult, int length, StringComparison stringComparison, params string[] sections)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            if (parseResult.Sections.Count != length || parseResult.Sections.Count < sections.Length)\n            {\n                return false;\n            }\n\n            return CompareSections(parseResult.Sections, sections, stringComparison);\n        }\n\n        public static bool ContainsExactly(this ICoreParseResult parseResult, int length, params string[] sections)\n        {\n            return ContainsExactly(parseResult, length, StringComparison.OrdinalIgnoreCase, sections);\n        }\n\n        public static bool ContainsExactly(this ICoreParseResult parseResult, params string[] sections)\n        {\n            return ContainsExactly(parseResult, sections.Length, sections);\n        }\n\n        public static bool ContainsAtLeast(this ICoreParseResult parseResult, int minimumLength, StringComparison stringComparison, params string[] sections)\n        {\n            parseResult = parseResult ?? throw new ArgumentNullException(nameof(parseResult));\n\n            if (parseResult.Sections.Count < minimumLength || parseResult.Sections.Count < sections.Length)\n            {\n                return false;\n            }\n\n            return CompareSections(parseResult.Sections, sections, stringComparison);\n        }\n\n        public static bool ContainsAtLeast(this ICoreParseResult parseResult, int minimumLength, params string[] sections)\n        {\n            return ContainsAtLeast(parseResult, minimumLength, StringComparison.OrdinalIgnoreCase, sections);\n        }\n\n        public static bool ContainsAtLeast(this ICoreParseResult parseResult, params string[] sections)\n        {\n            return ContainsAtLeast(parseResult, minimumLength: sections.Length, sections);\n        }\n\n        private static bool CompareSections(IReadOnlyList<string> parseSections, string[] sections, StringComparison stringComparison)\n        {\n            for (int index = 0; index < sections.Length; index++)\n            {\n                if (!string.Equals(parseSections[index], sections[index], stringComparison))\n                {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Parsing/CoreParser.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Microsoft.Repl.Parsing\n{\n    public class CoreParser : IParser<ICoreParseResult>\n    {\n        public ICoreParseResult Parse(string commandText, int caretPosition)\n        {\n            commandText = commandText ?? throw new ArgumentNullException(nameof(commandText));\n\n            List<string> sections = commandText.Split(' ').ToList();\n            // We can't use StringSplitOptions.RemoveEmptyEntries because it\n            // is more aggressive than we need, so we need to do it ourselves.\n            RemoveEmptyEntries(sections);\n            Dictionary<int, int> sectionStartLookup = new Dictionary<int, int>();\n            HashSet<int> quotedSections = new HashSet<int>();\n            int runningIndex = 0;\n            int selectedSection = -1;\n            int caretPositionWithinSelectedSection = 0;\n            bool isInQuotedSection = false;\n\n            for (int i = 0; i < sections.Count; ++i)\n            {\n                int thisSectionLength = sections[i].Length;\n                bool isLastSection = i == sections.Count - 1;\n\n                //If currently in a quoted section, combine with the previous section, check to see if this section closes the quotes\n                if (isInQuotedSection)\n                {\n                    //Combine with the previous section\n                    sections[i - 1] += \" \" + sections[i];\n                    sections.RemoveAt(i--);\n\n                    //Check for the closing quote\n                    int sectionLength = sections[i].Length;\n                    bool justOneCharacter = sectionLength == 1;\n                    bool endsWithDoubleQuote = sections[i][sectionLength - 1] == '\"';\n                    bool lastCharacterIsEscaped = !justOneCharacter && sections[i][sectionLength - 2] == '\\\\';\n                    if (endsWithDoubleQuote && !lastCharacterIsEscaped)\n                    {\n                        isInQuotedSection = false;\n                    }\n                }\n                //Not in a quoted section, check to see if we're starting one (and not finishing it at the same time)\n                else\n                {\n                    sectionStartLookup[i] = runningIndex;\n\n                    if (thisSectionLength > 0)\n                    {\n                        bool startsWithDoubleQuote = sections[i][0] == '\"';\n                        bool justOneCharacter = thisSectionLength == 1;\n                        bool endsWithDoubleQuote = sections[i][thisSectionLength - 1] == '\"';\n                        bool lastCharacterIsEscaped = !justOneCharacter && sections[i][thisSectionLength - 2] == '\\\\';\n                        if (startsWithDoubleQuote && (!endsWithDoubleQuote || lastCharacterIsEscaped))\n                        {\n                            isInQuotedSection = true;\n                        }\n                    }\n                }\n\n                //Update the running index, adding one for all but the last element to account for the spaces between the sections\n                runningIndex += thisSectionLength + (isLastSection ? 0 : 1);\n\n                //If the selected section hasn't been determined yet, and the end of the text is past the caret, set the selected\n                //  section to the current section and set the initial value for the caret position within the selected section.\n                //  Note that the caret position within the selected section, unlike the other positions, accounts for escape\n                //  sequences and must be fixed up when escape sequences are removed\n                if (selectedSection == -1 && runningIndex > caretPosition)\n                {\n                    selectedSection = i;\n                    caretPositionWithinSelectedSection = caretPosition - sectionStartLookup[i];\n                }\n            }\n\n            //Unescape the sections\n            //  Note that this isn't combined with the above loop to avoid additional complexity in the quoted section case\n            for (int i = 0; i < sections.Count; ++i)\n            {\n                string s = sections[i];\n\n                //Trim quotes if needed\n                if (s.Length > 1)\n                {\n                    if (s[0] == s[s.Length - 1] && s[0] == '\"')\n                    {\n                        s = s.Substring(1, s.Length - 2);\n                        quotedSections.Add(i);\n\n                        //Fix up the caret position in the text\n                        if (selectedSection == i)\n                        {\n                            //If the caret was on the closing quote, back up to the last character of the section\n                            if (caretPositionWithinSelectedSection == s.Length - 1)\n                            {\n                                caretPositionWithinSelectedSection -= 2;\n                            }\n                            //If the caret was after the opening quote, back up one\n                            else if (caretPositionWithinSelectedSection > 0)\n                            {\n                                --caretPositionWithinSelectedSection;\n                            }\n                        }\n                    }\n                }\n\n                for (int j = 0; j < s.Length - 1; ++j)\n                {\n                    if (s[j] == '\\\\')\n                    {\n                        if (s[j + 1] == '\\\\' || s[j + 1] == '\"')\n                        {\n                            s = s.Substring(0, j) + s.Substring(j + 1);\n\n                            //If we're changing the selected section, and we're removing a character\n                            //  from before the caret position, back the caret position up to account for it\n                            if (selectedSection == i && j < caretPositionWithinSelectedSection)\n                            {\n                                --caretPositionWithinSelectedSection;\n                            }\n                        }\n                    }\n                }\n\n                sections[i] = s;\n            }\n\n            if (selectedSection == -1)\n            {\n                selectedSection = sections.Count - 1;\n                caretPositionWithinSelectedSection = sections[selectedSection].Length;\n            }\n\n            return new CoreParseResult(caretPosition, caretPositionWithinSelectedSection, commandText, sections, selectedSection, sectionStartLookup, quotedSections);\n        }\n\n        private static void RemoveEmptyEntries(List<string> sections)\n        {\n            if (sections.Count < 2)\n            {\n                return;\n            }\n\n            // We want to remove empty spaces from the beginning, and from the middle\n            // but not from the end.\n            for (int index = 0; index < sections.Count - 1; index++)\n            {\n                if (sections[index].Length == 0)\n                {\n                    sections.RemoveAt(index);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Parsing/ICoreParseResult.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.Repl.Parsing\n{\n    public interface ICoreParseResult\n    {\n        int CaretPositionWithinCommandText { get; }\n\n        int CaretPositionWithinSelectedSection { get; }\n\n        string CommandText { get; }\n\n        IReadOnlyList<string> Sections { get; }\n\n        bool IsQuotedSection(int index);\n\n        int SelectedSection { get; }\n\n        IReadOnlyDictionary<int, int> SectionStartLookup { get; }\n\n        ICoreParseResult Slice(int numberOfLeadingSectionsToRemove);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Parsing/IParser.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.txt file in the project root for more information.\n\nnamespace Microsoft.Repl.Parsing\n{\n    public interface IParser\n    {\n        ICoreParseResult Parse(string commandText, int caretPosition);\n    }\n\n    public interface IParser<out TParseResult> : IParser\n    {\n        new TParseResult Parse(string commandText, int caretPosition);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Properties/AssemblyInfo.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.txt file in the project root for more information.\n\nusing System.Runtime.CompilerServices;\n\n[assembly: InternalsVisibleTo(\"Microsoft.Repl.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Design\", \"CA1031:Do not catch general exception types\", Justification = \"This is done commonly throughout the codebase to catch unexpected errors.\")]\n\n"
  },
  {
    "path": "src/Microsoft.Repl/Resources/Strings.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\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\nnamespace Microsoft.Repl.Resources {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Strings {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Strings() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Microsoft.Repl.Resources.Strings\", typeof(Strings).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Command execution cancelled.\n        /// </summary>\n        internal static string DefaultCommandDispatcher_Error_ExecutionWasCancelled {\n            get {\n                return ResourceManager.GetString(\"DefaultCommandDispatcher_Error_ExecutionWasCancelled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to No matching command found.\n        /// </summary>\n        internal static string DefaultCommandDispatcher_Error_NoMatchingCommand {\n            get {\n                return ResourceManager.GetString(\"DefaultCommandDispatcher_Error_NoMatchingCommand\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Execute &apos;help&apos; to see available commands.\n        /// </summary>\n        internal static string DefaultCommandDispatcher_Error_SeeHelp {\n            get {\n                return ResourceManager.GetString(\"DefaultCommandDispatcher_Error_SeeHelp\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Resources/Strings.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"DefaultCommandDispatcher_Error_ExecutionWasCancelled\" xml:space=\"preserve\">\n    <value>Command execution cancelled</value>\n  </data>\n  <data name=\"DefaultCommandDispatcher_Error_NoMatchingCommand\" xml:space=\"preserve\">\n    <value>No matching command found</value>\n  </data>\n  <data name=\"DefaultCommandDispatcher_Error_SeeHelp\" xml:space=\"preserve\">\n    <value>Execute 'help' to see available commands</value>\n  </data>\n</root>\n"
  },
  {
    "path": "src/Microsoft.Repl/Scripting/IScriptExecutor.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Microsoft.Repl.Scripting\n{\n    public interface IScriptExecutor\n    {\n        Task ExecuteScriptAsync(IShellState shellState, IEnumerable<string> commandTexts, CancellationToken cancellationToken);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Scripting/ScriptExecutor.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.Repl.Scripting\n{\n    public class ScriptExecutor<TProgramState, TParseResult> : IScriptExecutor\n        where TParseResult : ICoreParseResult\n    {\n        private readonly bool _hideScriptLinesFromHistory;\n\n        public ScriptExecutor(bool hideScriptLinesFromHistory = true)\n        {\n            _hideScriptLinesFromHistory = hideScriptLinesFromHistory;\n        }\n\n        public async Task ExecuteScriptAsync(IShellState shellState, IEnumerable<string> commandTexts, CancellationToken cancellationToken)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            commandTexts = commandTexts ?? throw new ArgumentNullException(nameof(commandTexts));\n\n            if (shellState.CommandDispatcher is ICommandDispatcher<TProgramState, TParseResult> dispatcher)\n            {\n                IDisposable suppressor = _hideScriptLinesFromHistory ? shellState.CommandHistory.SuspendHistory() : null;\n\n                using (suppressor)\n                {\n                    foreach (string commandText in commandTexts)\n                    {\n                        if (string.IsNullOrWhiteSpace(commandText))\n                        {\n                            continue;\n                        }\n\n                        if (cancellationToken.IsCancellationRequested)\n                        {\n                            break;\n                        }\n\n                        dispatcher.OnReady(shellState);\n                        shellState.InputManager.SetInput(shellState, commandText);\n                        await dispatcher.ExecuteCommandAsync(shellState, cancellationToken).ConfigureAwait(false);\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Shell.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.txt file in the project root for more information.\n\nusing System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Input;\nusing Microsoft.Repl.Suggestions;\n\nnamespace Microsoft.Repl\n{\n    public class Shell\n    {\n        public Shell(IShellState shellState)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            KeyHandlers.RegisterDefaultKeyHandlers(shellState.InputManager);\n            ShellState = shellState;\n        }\n\n        public Shell(ICommandDispatcher dispatcher, ISuggestionManager suggestionManager = null, IConsoleManager consoleManager = null)\n            : this(new ShellState(dispatcher, suggestionManager, consoleManager: consoleManager))\n        {\n        }\n\n        public IShellState ShellState { get; }\n\n        public Task RunAsync(CancellationToken cancellationToken)\n        {\n            ShellState.CommandDispatcher.OnReady(ShellState);\n            return ShellState.InputManager.StartAsync(ShellState, cancellationToken);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/ShellState.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Input;\nusing Microsoft.Repl.Suggestions;\n\nnamespace Microsoft.Repl\n{\n    public class ShellState : IShellState\n    {\n        public ShellState(ICommandDispatcher commandDispatcher, ISuggestionManager suggestionManager = null, IInputManager inputManager = null, ICommandHistory commandHistory = null, IConsoleManager consoleManager = null)\n        {\n            InputManager = inputManager ?? new InputManager();\n            CommandHistory = commandHistory ?? new CommandHistory();\n            ConsoleManager = consoleManager ?? new ConsoleManager();\n            CommandDispatcher = commandDispatcher;\n            SuggestionManager = suggestionManager ?? new SuggestionManager();\n        }\n\n        public IInputManager InputManager { get; }\n\n        public ICommandHistory CommandHistory { get; }\n\n        public IConsoleManager ConsoleManager { get; }\n\n        public ICommandDispatcher CommandDispatcher { get; }\n\n        public bool IsExiting { get; set; }\n\n        public ISuggestionManager SuggestionManager { get; }\n\n        public void MoveCarets(int positions)\n        {\n            ConsoleManager.MoveCaret(positions);\n            InputManager.MoveCaret(positions);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Suggestions/FileSystemCompletion.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\n\nnamespace Microsoft.Repl.Suggestions\n{\n    public static class FileSystemCompletion\n    {\n        public static IEnumerable<string> GetCompletions(string prefix)\n        {\n            prefix = prefix ?? throw new ArgumentNullException(nameof(prefix));\n\n            if (prefix.StartsWith(\"\\\"\", StringComparison.Ordinal))\n            {\n                prefix = prefix.Substring(1);\n\n                int lastQuote = prefix.LastIndexOf('\\\"');\n\n                if (lastQuote > -1)\n                {\n                    prefix = prefix.Remove(lastQuote, 1);\n                }\n\n                while (prefix.EndsWith($\"{Path.DirectorySeparatorChar}{Path.DirectorySeparatorChar}\", StringComparison.OrdinalIgnoreCase))\n                {\n                    prefix = prefix.Substring(0, prefix.Length - 1);\n                }\n            }\n\n            int lastPathIndex = prefix.LastIndexOfAny(new[] { '\\\\', '/' });\n            if (lastPathIndex < 0)\n            {\n                return null;\n            }\n\n            string dir = prefix.Substring(0, lastPathIndex + 1);\n\n            if (dir.IndexOfAny(Path.GetInvalidPathChars()) > -1)\n            {\n                return null;\n            }\n\n            string partPrefix = prefix.Substring(lastPathIndex + 1);\n            if (Directory.Exists(dir))\n            {\n                return Directory.EnumerateDirectories(dir).Where(x => Path.GetFileName(x).StartsWith(partPrefix, StringComparison.OrdinalIgnoreCase))\n                    .Union(Directory.EnumerateFiles(dir).Where(x => Path.GetFileName(x).StartsWith(partPrefix, StringComparison.OrdinalIgnoreCase))).Select(x => x.IndexOf(' ', StringComparison.Ordinal) > -1 ? $\"\\\"{x}\\\"\" : x);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Suggestions/ISuggestionManager.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.txt file in the project root for more information.\n\nnamespace Microsoft.Repl.Suggestions\n{\n    public interface ISuggestionManager\n    {\n        void NextSuggestion(IShellState shellState);\n\n        void PreviousSuggestion(IShellState shellState);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Suggestions/SuggestionManager.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.Repl.Suggestions\n{\n    public class SuggestionManager : ISuggestionManager\n    {\n        private int _currentSuggestion;\n        private IReadOnlyList<string> _suggestions;\n        private ICoreParseResult _expected;\n\n        public void NextSuggestion(IShellState shellState)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            string line = shellState.InputManager.GetCurrentBuffer();\n            ICoreParseResult parseResult = shellState.CommandDispatcher.Parser.Parse(line, shellState.InputManager.CaretPosition);\n            string currentSuggestion;\n\n            //Check to see if we're continuing before querying for suggestions again\n            if (_expected != null\n                && string.Equals(_expected.CommandText, parseResult.CommandText, StringComparison.Ordinal)\n                && _expected.SelectedSection == parseResult.SelectedSection\n                && _expected.CaretPositionWithinSelectedSection == parseResult.CaretPositionWithinSelectedSection)\n            {\n                if (_suggestions == null || _suggestions.Count == 0)\n                {\n                    return;\n                }\n\n                _currentSuggestion = (_currentSuggestion + 1) % _suggestions.Count;\n                currentSuggestion = _suggestions[_currentSuggestion];\n            }\n            else\n            {\n                _currentSuggestion = 0;\n                _suggestions = shellState.CommandDispatcher.CollectSuggestions(shellState);\n\n                if (_suggestions == null || _suggestions.Count == 0)\n                {\n                    return;\n                }\n\n                currentSuggestion = _suggestions[0];\n            }\n\n            //We now have a suggestion, take the command text leading up to the section being suggested for,\n            //  concatenate that and the suggestion text, turn it in to keys, submit it to the input manager,\n            //  reset the caret, store the parse result of the new text as what's expected for a continuation\n            string newText = parseResult.CommandText.Substring(0, parseResult.SectionStartLookup[parseResult.SelectedSection]) + currentSuggestion;\n            _expected = shellState.CommandDispatcher.Parser.Parse(newText, newText.Length);\n            shellState.InputManager.SetInput(shellState, newText);\n        }\n\n        public void PreviousSuggestion(IShellState shellState)\n        {\n            shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));\n\n            string line = shellState.InputManager.GetCurrentBuffer();\n            ICoreParseResult parseResult = shellState.CommandDispatcher.Parser.Parse(line, shellState.InputManager.CaretPosition);\n            string currentSuggestion;\n\n            //Check to see if we're continuing before querying for suggestions again\n            if (_expected != null\n                && string.Equals(_expected.CommandText, parseResult.CommandText, StringComparison.Ordinal)\n                && _expected.SelectedSection == parseResult.SelectedSection\n                && _expected.CaretPositionWithinSelectedSection == parseResult.CaretPositionWithinSelectedSection)\n            {\n                if (_suggestions == null || _suggestions.Count == 0)\n                {\n                    return;\n                }\n\n                _currentSuggestion = (_currentSuggestion - 1 + _suggestions.Count) % _suggestions.Count;\n                currentSuggestion = _suggestions[_currentSuggestion];\n            }\n            else\n            {\n                _suggestions = shellState.CommandDispatcher.CollectSuggestions(shellState);\n                _currentSuggestion = _suggestions.Count - 1;\n\n                if (_suggestions == null || _suggestions.Count == 0)\n                {\n                    return;\n                }\n\n                currentSuggestion = _suggestions[_suggestions.Count - 1];\n            }\n\n            //We now have a suggestion, take the command text leading up to the section being suggested for,\n            //  concatenate that and the suggestion text, turn it in to keys, submit it to the input manager,\n            //  reset the caret, store the parse result of the new text as what's expected for a continuation\n            string newText = parseResult.CommandText.Substring(0, parseResult.SectionStartLookup[parseResult.SelectedSection]) + currentSuggestion;\n            _expected = shellState.CommandDispatcher.Parser.Parse(newText, newText.Length);\n            shellState.InputManager.SetInput(shellState, newText);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Repl/Utils.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.Repl\n{\n    public static class Utils\n    {\n        public static string Stringify(this IReadOnlyList<char> keys)\n        {\n            return string.Join(\"\", keys);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Directory.Build.props",
    "content": "<Project>\n  <Import Project=\"$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))\" />\n\n  <PropertyGroup>\n    <!-- The Test Projects all need to use a TargetFramework that matches the .NET SDK specified in global.json -->\n    <TestProjectTargetFramework>net9.0</TestProjectTargetFramework>\n    <RollForward>Major</RollForward>\n  </PropertyGroup>\n\n</Project>\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/ApiDefinitionReaderStub.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.txt file in the project root for more information.\n\nusing System;\nusing System.IO;\nusing Microsoft.HttpRepl.OpenApi;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class ApiDefinitionReaderStub : IApiDefinitionReader\n    {\n        private ApiDefinition _apiDefinition;\n\n        public ApiDefinitionReaderStub(ApiDefinition apiDefinition)\n        {\n            _apiDefinition = apiDefinition;\n        }\n\n        public ApiDefinitionParseResult CanHandle(string document)\n        {\n            JObject doc;\n            using (StringReader stringReader = new StringReader(document))\n            {\n                JsonSerializer serializer = new JsonSerializer();\n                doc = (JObject)serializer.Deserialize(stringReader, typeof(JObject));\n            }\n\n            return (doc[\"fakeApi\"]?.ToString() ?? \"\").StartsWith(\"1.\", StringComparison.Ordinal) ? new ApiDefinitionParseResult(true, null, null) : ApiDefinitionParseResult.Failed;\n        }\n\n        public ApiDefinitionParseResult ReadDefinition(string document, Uri sourceUri)\n        {\n            return new ApiDefinitionParseResult(true, _apiDefinition, null);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/FakePreferences.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public sealed class FakePreferences : IPreferences\n    {\n        private readonly Dictionary<string, string> _currentPreferences;\n\n        public FakePreferences()\n        {\n            DefaultPreferences = new Dictionary<string, string>();\n            _currentPreferences = new();\n        }\n\n        public IReadOnlyDictionary<string, string> DefaultPreferences { get; }\n        public IReadOnlyDictionary<string, string> CurrentPreferences => _currentPreferences;\n\n        public bool GetBoolValue(string preference, bool defaultValue = false)\n        {\n            if (CurrentPreferences.TryGetValue(preference, out string value) && bool.TryParse(value, out bool result))\n            {\n                return result;\n            }\n\n            return defaultValue;\n        }\n\n        public AllowedColors GetColorValue(string preference, AllowedColors defaultValue = AllowedColors.None)\n        {\n            if (CurrentPreferences.TryGetValue(preference, out string value) && Enum.TryParse(value, true, out AllowedColors result))\n            {\n                return result;\n            }\n\n            return defaultValue;\n        }\n\n        public int GetIntValue(string preference, int defaultValue = 0)\n        {\n            if (CurrentPreferences.TryGetValue(preference, out string value) && int.TryParse(value, out int result))\n            {\n                return result;\n            }\n\n            return defaultValue;\n        }\n\n        public string GetValue(string preference, string defaultValue = null)\n        {\n            if (CurrentPreferences.TryGetValue(preference, out string value))\n            {\n                return value;\n            }\n\n            return defaultValue;\n        }\n\n        public bool SetValue(string preference, string value)\n        {\n            _currentPreferences[preference] = value;\n            return true;\n        }\n\n        public bool TryGetValue(string preference, out string value) => CurrentPreferences.TryGetValue(preference, out value);\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/FileSystemStub.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing Microsoft.HttpRepl.FileSystem;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class FileSystemStub : IFileSystem\n    {\n        public void DeleteFile(string path)\n        {\n\n        }\n\n        public bool FileExists(string path)\n        {\n            return default;\n        }\n\n        public string GetTempFileName(string fileExtension)\n        {\n            return default;\n        }\n\n        public byte[] ReadAllBytesFromFile(string path)\n        {\n            return default;\n        }\n\n        public string[] ReadAllLinesFromFile(string path)\n        {\n            return default;\n        }\n\n        public void WriteAllLinesToFile(string path, IEnumerable<string> contents)\n        {\n\n        }\n\n        public void WriteAllTextToFile(string path, string contents)\n        {\n\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/LoggingConsoleManagerDecorator.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.txt file in the project root for more information.\n\nusing System;\nusing System.Text;\nusing System.Threading;\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class LoggingConsoleManagerDecorator : IConsoleManager\n    {\n        private readonly IConsoleManager _baseConsole;\n        private readonly StringBuilder _log;\n\n        public LoggingConsoleManagerDecorator(IConsoleManager console)\n        {\n            _baseConsole = console;\n            _log = new StringBuilder();\n        }\n\n        public string LoggedOutput => _log.ToString();\n        public bool WasClearCalled { get; private set; }\n\n        #region IConsoleManager\n        public Point Caret => _baseConsole.Caret;\n\n        public IWritable Error => _baseConsole.Error;\n\n        public bool IsKeyAvailable => _baseConsole.IsKeyAvailable;\n\n        public bool IsCaretVisible { get => _baseConsole.IsCaretVisible; set => _baseConsole.IsCaretVisible = value; }\n\n        public bool AllowOutputRedirection => _baseConsole.AllowOutputRedirection;\n\n        public IDisposable AddBreakHandler(Action onBreak)\n        {\n            return _baseConsole.AddBreakHandler(onBreak);\n        }\n\n        public void Clear()\n        {\n            _baseConsole.Clear();\n            WasClearCalled = true;\n        }\n\n        public void MoveCaret(int positions)\n        {\n            _baseConsole.MoveCaret(positions);\n        }\n\n        public ConsoleKeyInfo ReadKey(CancellationToken cancellationToken)\n        {\n            return _baseConsole.ReadKey(cancellationToken);\n        }\n\n        public void Write(char c)\n        {\n            _log.Append(c);\n            _baseConsole.Write(c);\n        }\n\n        public void Write(string s)\n        {\n            _log.Append(s);\n            _baseConsole.Write(s);\n        }\n\n        public void WriteLine()\n        {\n            _log.AppendLine();\n            _baseConsole.WriteLine();\n        }\n\n        public void WriteLine(string s)\n        {\n            _log.AppendLine(s);\n            _baseConsole.WriteLine(s);\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/Microsoft.HttpRepl.Fakes.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>$(TestProjectTargetFramework)</TargetFramework>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <FrameworkReference Include=\"Microsoft.AspNetCore.App\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Moq\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"Swashbuckle.AspNetCore\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"System.Net.Http\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"$(RepoSource)\\Microsoft.HttpRepl\\Microsoft.HttpRepl.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/MockCommand.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class MockCommand : ICommand<object, ICoreParseResult>\n    {\n        public string Name { get; }\n\n        public MockCommand(string commandName)\n        {\n            Name = commandName;\n        }\n\n        public bool? CanHandle(IShellState shellState, object programState, ICoreParseResult parseResult)\n        {\n            return (bool?)true;\n        }\n\n        public Task ExecuteAsync(IShellState shellState, object programState, ICoreParseResult parseResult, CancellationToken cancellationToken)\n        {\n            return Task.CompletedTask;\n        }\n\n        public string GetHelpDetails(IShellState shellState, object programState, ICoreParseResult parseResult)\n        {\n            return null;\n        }\n\n        public string GetHelpSummary(IShellState shellState, object programState)\n        {\n            return null;\n        }\n\n        public IEnumerable<string> Suggest(IShellState shellState, object programState, ICoreParseResult parseResult)\n        {\n            return new[] { Name };\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/MockConsoleManager.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Threading;\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class MockConsoleManager : IConsoleManager\n    {\n        private CancellationTokenSource _cancellationTokenSource;\n        private List<ConsoleKeyInfo> _consoleKeyInfo;\n        private int _nextKeyIndex;\n        private StringBuilder _outputTracking = new StringBuilder();\n\n        public MockConsoleManager(IEnumerable<ConsoleKeyInfo> consoleKeyInfo, CancellationTokenSource cancellationTokenSource)\n        {\n            _cancellationTokenSource = cancellationTokenSource;\n            _consoleKeyInfo = new List<ConsoleKeyInfo>(consoleKeyInfo);\n        }\n\n        public MockConsoleManager()\n        {\n            _cancellationTokenSource = new CancellationTokenSource();\n        }\n\n        public string Output => _outputTracking.ToString();\n\n        public Point Caret => throw new NotImplementedException();\n\n        public Point CommandStart => throw new NotImplementedException();\n\n        public int CaretPosition { get; set; }\n\n        public IWritable Error => new MockWritable();\n\n        public bool IsKeyAvailable => _nextKeyIndex < _consoleKeyInfo.Count;\n\n        public void Clear()\n        {\n        }\n\n        public void MoveCaret(int offset)\n        {\n            CaretPosition += offset;\n        }\n\n        public ConsoleKeyInfo ReadKey(CancellationToken cancellationToken)\n        {\n            ConsoleKeyInfo currentKeyInfo = _nextKeyIndex < _consoleKeyInfo.Count ? _consoleKeyInfo[_nextKeyIndex] : new ConsoleKeyInfo();\n            _nextKeyIndex++;\n            if (_nextKeyIndex >= _consoleKeyInfo.Count)\n            {\n                _cancellationTokenSource.Cancel();\n            }\n            return currentKeyInfo;\n        }\n\n        public void ResetCommandStart()\n        {\n        }\n\n        public IDisposable AddBreakHandler(Action onBreak)\n        {\n            return null;\n        }\n\n        public void Write(char c) => _outputTracking.Append(c);\n\n        public void Write(string s) => _outputTracking.Append(s);\n\n        public void WriteLine() => _outputTracking.AppendLine();\n\n        public void WriteLine(string s) => _outputTracking.AppendLine(s);\n\n        public bool IsCaretVisible { get => true; }\n\n        bool IWritable.IsCaretVisible { get => true; set => value = true; }\n\n        public bool AllowOutputRedirection => true;\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/MockHttpContent.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.txt file in the project root for more information.\n\nusing System.IO;\nusing System.Net;\nusing System.Net.Http;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class MockHttpContent : HttpContent\n    {\n        public string Content { get; }\n\n        public MockHttpContent(string content)\n        {\n            Content = content ?? string.Empty;\n        }\n\n        protected async override Task SerializeToStreamAsync(Stream stream, TransportContext context)\n        {\n            byte[] byteArray = Encoding.ASCII.GetBytes(Content);\n            await stream.WriteAsync(byteArray, 0, byteArray.Length);\n        }\n\n        protected override bool TryComputeLength(out long length)\n        {\n            length = Content.Length;\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/MockHttpMessageHandler.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class MockHttpMessageHandler : HttpMessageHandler\n    {\n        private readonly string _contentType;\n        private readonly string _fileContents;\n        private readonly string _header;\n        private readonly bool _readFromFile;\n        private readonly IDictionary<string, string> _urlsWithResponse;\n\n        public MockHttpMessageHandler(IDictionary<string, string> urlsWithResponse,\n            string header,\n            bool readFromFile,\n            string fileContents,\n            string contentType)\n        {\n            _contentType = contentType;\n            _fileContents = fileContents;\n            _header = header;\n            _readFromFile = readFromFile;\n            _urlsWithResponse = urlsWithResponse;\n        }\n\n        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\n        {\n            string absoluteUri = request.RequestUri.AbsoluteUri;\n            _urlsWithResponse.TryGetValue(absoluteUri, out string responseContent);\n\n            HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK);\n            httpResponseMessage.RequestMessage = request;\n\n            if (_readFromFile)\n            {\n                httpResponseMessage.Content = new MockHttpContent(_fileContents);\n            }\n            else if (!string.IsNullOrEmpty(_header))\n            {\n                httpResponseMessage.Headers.Add(_header, responseContent);\n            }\n            else\n            {\n                httpResponseMessage.Content = new MockHttpContent(responseContent);\n            }\n\n            if (!string.IsNullOrEmpty(_contentType) && httpResponseMessage.Content != null)\n            {\n                httpResponseMessage.Content.Headers.Add(\"Content-Type\", _contentType);\n            }\n\n            return Task.FromResult(httpResponseMessage);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/MockInputManager.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.txt file in the project root for more information.\n\nusing System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Input;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class MockInputManager : IInputManager\n    {\n        private string _inputBuffer;\n\n        public int CaretPosition { get; private set; }\n\n        public MockInputManager(string inputBuffer)\n        {\n            _inputBuffer = inputBuffer;\n        }\n\n        public void MoveCaret(int positions)\n        {\n\n        }\n\n        public bool IsOverwriteMode { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }\n\n        public IInputManager RegisterKeyHandler(ConsoleKey key, AsyncKeyPressHandler handler)\n        {\n            return new InputManager();\n        }\n\n        public IInputManager RegisterKeyHandler(ConsoleKey key, ConsoleModifiers modifiers, AsyncKeyPressHandler handler)\n        {\n            return new InputManager();\n        }\n\n        public void ResetInput()\n        {\n        }\n\n        public Task StartAsync(IShellState state, CancellationToken cancellationToken)\n        {\n            throw new NotImplementedException();\n        }\n\n        public void SetInput(IShellState state, string input)\n        {\n            _inputBuffer = input;\n        }\n\n        public string GetCurrentBuffer()\n        {\n            return _inputBuffer;\n        }\n\n        public void RemovePreviousCharacter(IShellState state)\n        {\n        }\n\n        public void RemoveCurrentCharacter(IShellState state)\n        {\n        }\n\n        public void Clear(IShellState state)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/MockWritable.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    internal class MockWritable : IWritable\n    {\n        public void Write(char c)\n        {\n        }\n\n        public void Write(string s)\n        {\n        }\n\n        public void WriteLine()\n        {\n        }\n\n        public void WriteLine(string s)\n        {\n        }\n\n        public bool IsCaretVisible { get => true; set => value = true; }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/MockedFileSystem.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Security.Cryptography;\nusing System.Text;\nusing Microsoft.HttpRepl.FileSystem;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class MockedFileSystem : IFileSystem\n    {\n        private readonly Dictionary<string, string> _files = new Dictionary<string, string>();\n\n        public MockedFileSystem AddFile(string path, string contents)\n        {\n            _files[path] = contents;\n            return this;\n        }\n\n        public string ReadFile(string path)\n        {\n            return _files[path];\n        }\n\n        public void DeleteFile(string path)\n        {\n            if (_files.ContainsKey(path))\n            {\n                _files.Remove(path);\n            }\n        }\n\n        public bool FileExists(string path)\n        {\n            if (string.IsNullOrWhiteSpace(path))\n            {\n                return false;\n            }\n\n            return _files.ContainsKey(path);\n        }\n\n        public byte[] ReadAllBytesFromFile(string path)\n        {\n            if (path == null)\n            {\n                throw new ArgumentNullException(path);\n            }\n\n            if (!FileExists(path))\n            {\n                throw new FileNotFoundException();\n            }\n\n            return Encoding.UTF8.GetBytes(_files[path]);\n        }\n\n        public string[] ReadAllLinesFromFile(string path)\n        {\n            string alltext = _files[path];\n            return alltext.Split(new string[] { \"\\r\\n\", \"\\r\", \"\\n\" }, StringSplitOptions.None);\n        }\n\n        public void WriteAllLinesToFile(string path, IEnumerable<string> contents)\n        {\n            _files[path] = string.Join(Environment.NewLine, contents);\n        }\n\n        public void WriteAllTextToFile(string path, string contents)\n        {\n            _files[path] = contents;\n        }\n\n        public string GetTempFileName(string fileExtension)\n        {\n            string path = GetRandomFileName();\n            _files[path] = \"\";\n            return path;\n        }\n\n        private string GetRandomFileName()\n        {\n            byte[] bytes = RandomNumberGenerator.GetBytes(9);\n            string path = Convert.ToBase64String(bytes);\n            return path;\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/MockedShellState.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Input;\nusing Microsoft.Repl.Suggestions;\nusing Moq;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class MockedShellState : IShellState\n    {\n        private readonly ShellState _shellState;\n        private readonly StringBuilder _output = new StringBuilder();\n        public MockedShellState(IInputManager inputManager = null)\n        {\n            DefaultCommandDispatcher<object> defaultCommandDispatcher = DefaultCommandDispatcher.Create(x => { }, new object());\n            Mock<IConsoleManager> mockedConsoleManager = new Mock<IConsoleManager>();\n            Mock<IWritable> mockedErrorWritable = new Mock<IWritable>();\n            mockedErrorWritable.Setup(x => x.WriteLine(It.IsAny<string>())).Callback((string s) => ErrorMessage = s);\n            mockedConsoleManager.Setup(x => x.Error).Returns(mockedErrorWritable.Object);\n            mockedConsoleManager.Setup(x => x.Write(It.IsAny<string>())).Callback((string s) => _output.Append(s));\n            mockedConsoleManager.Setup(x => x.WriteLine(It.IsAny<string>())).Callback((string s) => _output.AppendLine(s));\n\n            _shellState = new ShellState(defaultCommandDispatcher, inputManager: inputManager, consoleManager: mockedConsoleManager.Object);\n        }\n\n        public string ErrorMessage { get; private set; }\n\n        public List<string> Output => _output.ToString().Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries).ToList();\n\n        public IInputManager InputManager => _shellState.InputManager;\n\n        public ICommandHistory CommandHistory => _shellState.CommandHistory;\n\n        public IConsoleManager ConsoleManager => _shellState.ConsoleManager;\n\n        public ICommandDispatcher CommandDispatcher => _shellState.CommandDispatcher;\n\n        public ISuggestionManager SuggestionManager => _shellState.SuggestionManager;\n\n        public bool IsExiting { get => _shellState.IsExiting; set => _shellState.IsExiting = value; }\n\n        public void MoveCarets(int positions)\n        {\n            ConsoleManager?.MoveCaret(positions);\n            InputManager?.MoveCaret(positions);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/NullConsoleManager.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.txt file in the project root for more information.\n\nusing System;\nusing System.Threading;\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class NullConsoleManager : IConsoleManager\n    {\n        public Point Caret => default(Point);\n\n        public Point CommandStart => default(Point);\n\n        public int CaretPosition => default(int);\n\n        public IWritable Error => default(IWritable);\n\n        public bool IsKeyAvailable => default;\n\n        public bool IsCaretVisible { get => default; set => _ = value; }\n\n        public bool AllowOutputRedirection => true;\n\n        public IDisposable AddBreakHandler(Action onBreak)\n        {\n            return default;\n        }\n\n        public void Clear()\n        {\n        }\n\n        public void MoveCaret(int positions)\n        {\n        }\n\n        public ConsoleKeyInfo ReadKey(CancellationToken cancellationToken)\n        {\n            return default;\n        }\n\n        public void ResetCommandStart()\n        {\n        }\n\n        public void Write(char c)\n        {\n        }\n\n        public void Write(string s)\n        {\n        }\n\n        public void WriteLine()\n        {\n        }\n\n        public void WriteLine(string s)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/NullPreferences.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl.ConsoleHandling;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class NullPreferences : IPreferences\n    {\n        public IReadOnlyDictionary<string, string> CurrentPreferences => null;\n        public IReadOnlyDictionary<string, string> DefaultPreferences => null;\n\n        public AllowedColors GetColorValue(string preference, AllowedColors defaultValue = default)\n        {\n            return default;\n        }\n\n        public int GetIntValue(string preference, int defaultValue = default)\n        {\n            return defaultValue;\n        }\n\n        public bool GetBoolValue(string preference, bool defaultValue = false)\n        {\n            return defaultValue;\n        }\n\n        public string GetValue(string preference, string defaultValue = default)\n        {\n            return defaultValue;\n        }\n\n        public bool SetValue(string preference, string value)\n        {\n            return false;\n        }\n\n        public bool TryGetValue(string preference, out string value)\n        {\n            value = null;\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/NullTelemetry.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class NullTelemetry : ITelemetry\n    {\n        private readonly IFirstTimeUseNoticeSentinel _firstTimeUseNoticeSentinel = new NullFirstTimeUseNoticeSentinel();\n\n        public bool Enabled => false;\n\n        public IFirstTimeUseNoticeSentinel FirstTimeUseNoticeSentinel => _firstTimeUseNoticeSentinel;\n\n        public void TrackEvent(string eventName, IReadOnlyDictionary<string, string> properties, IReadOnlyDictionary<string, double> measurements)\n        {\n\n        }\n    }\n\n    public class NullFirstTimeUseNoticeSentinel : IFirstTimeUseNoticeSentinel\n    {\n        public void CreateIfNotExists() { }\n\n        public bool Exists() => true;\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Fakes/TelemetryCollector.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.Fakes\n{\n    public class TelemetryCollector : ITelemetry\n    {\n        private List<CollectedTelemetry> _telemetry = new List<CollectedTelemetry>();\n\n        public bool Enabled => true;\n\n        public IFirstTimeUseNoticeSentinel FirstTimeUseNoticeSentinel => null;\n\n        public void TrackEvent(string eventName, IReadOnlyDictionary<string, string> properties, IReadOnlyDictionary<string, double> measurements)\n        {\n            _telemetry.Add(new CollectedTelemetry(eventName, properties, measurements));\n        }\n\n        public IReadOnlyList<CollectedTelemetry> Telemetry => _telemetry;\n\n\n        public class CollectedTelemetry\n        {\n            public string EventName { get; }\n            public IReadOnlyDictionary<string, string> Properties { get; }\n            public IReadOnlyDictionary<string, double> Measurements { get; }\n\n            public CollectedTelemetry(string eventName, IReadOnlyDictionary<string, string> properties, IReadOnlyDictionary<string, double> measurements)\n            {\n                EventName = eventName;\n                Properties = properties;\n                Measurements = measurements;\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/BaseIntegrationTest.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.txt file in the project root for more information.\n\nusing System;\nusing System.Linq;\nusing System.Text.RegularExpressions;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.IntegrationTests.Utilities;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\n\nnamespace Microsoft.HttpRepl.IntegrationTests\n{\n    public class BaseIntegrationTest\n    {\n        private static readonly Regex _dateRegex;\n        private static readonly string _dateReplacement;\n\n        static BaseIntegrationTest()\n        {\n            if (Environment.NewLine == \"\\r\\n\")\n            {\n                _dateRegex = new Regex(\"^Date: [A-Za-z]{3}, \\\\d{2} [A-Za-z]{3} \\\\d{4} \\\\d{2}:\\\\d{2}:\\\\d{2} GMT\\r$\", RegexOptions.Compiled | RegexOptions.Multiline);\n                _dateReplacement = \"Date: [Date]\\r\";\n            }\n            else\n            {\n                _dateRegex = new Regex(\"^Date: [A-Za-z]{3}, \\\\d{2} [A-Za-z]{3} \\\\d{4} \\\\d{2}:\\\\d{2}:\\\\d{2} GMT$\", RegexOptions.Compiled | RegexOptions.Multiline);\n                _dateReplacement = \"Date: [Date]\";\n            }\n        }\n\n        protected static string NormalizeOutput(string output, string baseUrl)\n        {\n            // The console implementation uses trailing whitespace when a new line's text is shorter than the previous\n            // line.  For example (the trailing * represent spaces):\n            // Line 1: (Disconnected)> run C:\\path\\to\\a\\test\\script\\file.txt\n            // Line 2: (Disconnected)> set base http://localhost:12345******\n            // This having this whitespace makes it harder to read/write test baselines, so here we'll trim each line\n            string result = string.Join(Environment.NewLine, output.Split(Environment.NewLine).Select(l => l.TrimEnd()));\n\n            // next, normalize the base URL from the test fixture\n            if (!string.IsNullOrEmpty(baseUrl))\n            {\n                result = result.Replace(baseUrl, \"[BaseUrl]\");\n            }\n\n            // next, normalize the date\n            result = _dateRegex.Replace(result, _dateReplacement);\n\n            // strip ansi begin/end formatting (bold, color)\n            result = Regex.Replace(result, @\"\\u001b\\[[0-9]*m\", string.Empty);\n\n            return result;\n        }\n\n        protected static async Task<string> RunTestScript(string scriptText, string baseAddress, IPreferences preferences = null, ITelemetry telemetry = null)\n        {\n            LoggingConsoleManagerDecorator console = new LoggingConsoleManagerDecorator(new NullConsoleManager());\n            preferences ??= new NullPreferences();\n            telemetry ??= new NullTelemetry();\n\n            using (var script = new TestScript(scriptText))\n            {\n                await Program.Start($\"run {script.FilePath}\".Split(' '), console, preferences, telemetry);\n            }\n\n            string output = console.LoggedOutput;\n            // remove the first line because it has the randomly generated script file name.\n            output = output.Substring(output.IndexOf(Environment.NewLine) + Environment.NewLine.Length);\n            output = NormalizeOutput(output, baseAddress);\n\n            return output;\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/Commands/ChangeDirectoryCommandTests.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.txt file in the project root for more information.\n\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.IntegrationTests.SampleApi;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.Commands\n{\n    public class ChangeDirectoryCommandTests : BaseIntegrationTest, IClassFixture<HttpCommandsFixture<SampleApiServerConfig>>\n    {\n        private readonly SampleApiServerConfig _serverConfig;\n\n        public ChangeDirectoryCommandTests(HttpCommandsFixture<SampleApiServerConfig> fixture)\n        {\n            _serverConfig = fixture.Config;\n        }\n\n        [Fact]\n        public async Task WithSwagger_MethodsAreUppercase()\n        {\n            string scriptText = $@\"connect {_serverConfig.BaseAddress}\nls\ncd api\nls\ncd Values\";\n            string output = await RunTestScript(scriptText, _serverConfig.BaseAddress);\n\n            // make sure to normalize newlines in the expected output\n            string expected = NormalizeOutput(@\"(Disconnected)> connect [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> ls\n.     []\napi   []\n\n[BaseUrl]/> cd api\n/api    []\n\n[BaseUrl]/api> ls\n.        []\n..       []\nValues   [GET|POST]\n\n[BaseUrl]/api> cd Values\n/api/Values    [GET|POST]\n\n[BaseUrl]/api/Values>\", null);\n\n            Assert.Equal(expected, output);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/Commands/EchoCommandTests.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.txt file in the project root for more information.\n\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.IntegrationTests.SampleApi;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.Commands\n{\n    public class EchoCommandTests : BaseIntegrationTest, IClassFixture<HttpCommandsFixture<SampleApiServerConfig>>\n    {\n        private readonly SampleApiServerConfig _serverConfig;\n\n        public EchoCommandTests(HttpCommandsFixture<SampleApiServerConfig> fixture)\n        {\n            _serverConfig = fixture.Config;\n        }\n\n        [Fact]\n        public async Task WithEchoOn_ShowsCorrectOutput()\n        {\n            string scriptText = $@\"connect --base {_serverConfig.BaseAddress}\necho on\";\n\n            string output = await RunTestScript(scriptText, _serverConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> connect --base [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> echo on\nRequest echoing is on\n\n[BaseUrl]/>\", null);\n\n            Assert.Equal(expected, output);\n        }\n\n        [Fact]\n        public async Task WithEchoOff_ShowsCorrectOutput()\n        {\n            string scriptText = $@\"connect --base {_serverConfig.BaseAddress}\necho off\";\n\n            string output = await RunTestScript(scriptText, _serverConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> connect --base [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> echo off\nRequest echoing is off\n\n[BaseUrl]/>\", null);\n\n            Assert.Equal(expected, output);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/Commands/GetCommandTests.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.txt file in the project root for more information.\n\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.IntegrationTests.SampleApi;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.Commands\n{\n    public class GetCommandTests : BaseIntegrationTest, IClassFixture<HttpCommandsFixture<SampleApiServerConfig>>\n    {\n        private readonly SampleApiServerConfig _serverConfig;\n\n        public GetCommandTests(HttpCommandsFixture<SampleApiServerConfig> fixture)\n        {\n            _serverConfig = fixture.Config;\n        }\n\n        [Fact]\n        public async Task WithoutParameter_ShowsCorrectOutput()\n        {\n            string scriptText = $@\"connect {_serverConfig.BaseAddress}\ncd api/values\nget\";\n\n            string output = await RunTestScript(scriptText, _serverConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> connect [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> cd api/values\n/api/values    [GET|POST]\n\n[BaseUrl]/api/values> get\nHTTP/1.1 200 OK\nContent-Type: application/json; charset=utf-8\nDate: [Date]\nServer: Kestrel\nTransfer-Encoding: chunked\n\n[\n  \"\"value1\"\",\n  \"\"value2\"\"\n]\n\n\n[BaseUrl]/api/values>\", null);\n\n            Assert.Equal(expected, output);\n        }\n\n        [Fact]\n        public async Task WithParameter_ShowsCorrectOutput()\n        {\n            string scriptText = $@\"connect {_serverConfig.BaseAddress}\ncd api/values\nget 5\";\n\n            string output = await RunTestScript(scriptText, _serverConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> connect [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> cd api/values\n/api/values    [GET|POST]\n\n[BaseUrl]/api/values> get 5\nHTTP/1.1 200 OK\nContent-Type: text/plain; charset=utf-8\nDate: [Date]\nServer: Kestrel\nTransfer-Encoding: chunked\n\nvalue\n\n\n[BaseUrl]/api/values>\", null);\n\n            Assert.Equal(expected, output);\n        }\n\n        [Fact]\n        public async Task InvalidPath_ShowsNotFoundMessage()\n        {\n            string scriptText = $@\"connect {_serverConfig.BaseAddress}\ncd api/invalidpath\nget\";\n\n            string output = await RunTestScript(scriptText, _serverConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> connect [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> cd api/invalidpath\nWarning: The '/api/invalidpath' endpoint is not present in the OpenAPI description\n/api/invalidpath    []\n\n[BaseUrl]/api/invalidpath> get\nHTTP/1.1 404 Not Found\nContent-Length: 0\nDate: [Date]\nServer: Kestrel\n\n\n\n\n[BaseUrl]/api/invalidpath>\", null);\n\n            Assert.Equal(expected, output);\n        }\n\n        [Fact]\n        public async Task WithNoSwaggerAndAbsoluteUrl_ShowsCorrectOutput()\n        {\n            string scriptText = $@\"get {_serverConfig.BaseAddress}/api/values\";\n\n            string output = await RunTestScript(scriptText, _serverConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> get [BaseUrl]/api/values\nHTTP/1.1 200 OK\nContent-Type: application/json; charset=utf-8\nDate: [Date]\nServer: Kestrel\nTransfer-Encoding: chunked\n\n[\n  \"\"value1\"\",\n  \"\"value2\"\"\n]\n\n\n(Disconnected)>\", null);\n\n            Assert.Equal(expected, output);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/Commands/HttpCommandsFixture.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.txt file in the project root for more information.\n\nusing System;\nusing Microsoft.HttpRepl.IntegrationTests.SampleApi;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.Commands\n{\n    public class HttpCommandsFixture<T> : IDisposable where T : SampleApiServerConfig, new()\n    {\n        private readonly SampleApiServer _testWebServer;\n\n        public T Config { get; } = new T();\n\n        public HttpCommandsFixture()\n        {\n            _testWebServer = new SampleApiServer(Config);\n            _testWebServer.Start();\n        }\n\n        public void Dispose()\n        {\n            _testWebServer.Stop();\n        }\n    }\n\n    public class DualHttpCommandsFixture<T> : IDisposable where T : SampleApiServerConfig, new()\n    {\n        private readonly SampleApiServer _swaggerServer;\n        private readonly SampleApiServer _nonSwaggerServer;\n\n        public T SwaggerConfig { get; } = new T();\n        public T NonSwaggerConfig { get; } = new T() { EnableSwagger = false };\n\n        public DualHttpCommandsFixture()\n        {\n            _swaggerServer = new SampleApiServer(SwaggerConfig);\n            _swaggerServer.Start();\n\n            _nonSwaggerServer = new SampleApiServer(NonSwaggerConfig);\n            _nonSwaggerServer.Start();\n        }\n\n        public void Dispose()\n        {\n            _swaggerServer.Stop();\n            _nonSwaggerServer.Stop();\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/Commands/ListCommandTests.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.txt file in the project root for more information.\n\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.IntegrationTests.SampleApi;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.Commands\n{\n    public class ListCommandTests : BaseIntegrationTest, IClassFixture<DualHttpCommandsFixture<SampleApiServerConfig>>\n    {\n        private readonly SampleApiServerConfig _swaggerServerConfig;\n        private readonly SampleApiServerConfig _nonSwaggerServerConfig;\n\n        public ListCommandTests(DualHttpCommandsFixture<SampleApiServerConfig> fixture)\n        {\n            _swaggerServerConfig = fixture.SwaggerConfig;\n            _nonSwaggerServerConfig = fixture.NonSwaggerConfig;\n        }\n\n        [Fact]\n        public async Task WithSwagger_ShowsAvailableSubpaths()\n        {\n            string scriptText = $@\"connect {_swaggerServerConfig.BaseAddress}\nls\ncd api\nls\";\n            string output = await RunTestScript(scriptText, _swaggerServerConfig.BaseAddress);\n\n            // make sure to normalize newlines in the expected output\n            string expected = NormalizeOutput(@\"(Disconnected)> connect [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> ls\n.     []\napi   []\n\n[BaseUrl]/> cd api\n/api    []\n\n[BaseUrl]/api> ls\n.        []\n..       []\nValues   [GET|POST]\n\n[BaseUrl]/api>\", null);\n\n            Assert.Equal(expected, output);\n        }\n\n        [Fact]\n        public async Task WithSwagger_ShowsControllerActionsWithHttpVerbs()\n        {\n            string scriptText = $@\"connect {_swaggerServerConfig.BaseAddress}\ncd api/Values\nls\";\n            string output = await RunTestScript(scriptText, _swaggerServerConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> connect [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> cd api/Values\n/api/Values    [GET|POST]\n\n[BaseUrl]/api/Values> ls\n.      [GET|POST]\n..     []\n{id}   [GET|PUT|DELETE]\n\n[BaseUrl]/api/Values>\", null);\n\n            Assert.Equal(expected, output);\n        }\n\n        [Fact]\n        public async Task WithoutSwagger_ShowsNoSubpaths()\n        {\n            string scriptText = $@\"connect --base {_nonSwaggerServerConfig.BaseAddress}\nls\ncd api\nls\";\n            string output = await RunTestScript(scriptText, _nonSwaggerServerConfig.BaseAddress);\n\n            // make sure to normalize newlines in the expected output\n            string expected = NormalizeOutput(@\"(Disconnected)> connect --base [BaseUrl]\nUsing a base address of [BaseUrl]/\nUnable to find an OpenAPI description\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> ls\nNo directory structure has been set, so there is nothing to list. Use the \"\"connect\"\" command to set a directory structure based on an OpenAPI description.\n\n[BaseUrl]/> cd api\n\n[BaseUrl]/api> ls\nNo directory structure has been set, so there is nothing to list. Use the \"\"connect\"\" command to set a directory structure based on an OpenAPI description.\n\n[BaseUrl]/api>\", null);\n\n            Assert.Equal(expected, output);\n        }\n\n        [Fact]\n        public async Task WithoutSwagger_ShowsNoActionsOrVerbs()\n        {\n            string scriptText = $@\"connect --base {_nonSwaggerServerConfig.BaseAddress}\ncd api/Values\nls\";\n            string output = await RunTestScript(scriptText, _nonSwaggerServerConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> connect --base [BaseUrl]\nUsing a base address of [BaseUrl]/\nUnable to find an OpenAPI description\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> cd api/Values\n\n[BaseUrl]/api/Values> ls\nNo directory structure has been set, so there is nothing to list. Use the \"\"connect\"\" command to set a directory structure based on an OpenAPI description.\n\n[BaseUrl]/api/Values>\", null);\n\n            Assert.Equal(expected, output);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/Commands/SetHeaderCommandTests.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.txt file in the project root for more information.\n\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.IntegrationTests.SampleApi;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.Commands\n{\n    public class SetHeaderCommandTests : BaseIntegrationTest, IClassFixture<HttpCommandsFixture<SampleApiServerConfig>>\n    {\n        private readonly SampleApiServerConfig _serverConfig;\n\n        public SetHeaderCommandTests(HttpCommandsFixture<SampleApiServerConfig> fixture)\n        {\n            _serverConfig = fixture.Config;\n        }\n\n        [Fact]\n        public async Task WithNameAndValueSpecified_AddsNewHeaderToListOfHeaders()\n        {\n            string scriptText = $@\"connect {_serverConfig.BaseAddress}\ncd api/values\necho on\nset header Accept application/json\nget\";\n\n            string output = await RunTestScript(scriptText, _serverConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> connect [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> cd api/values\n/api/values    [GET|POST]\n\n[BaseUrl]/api/values> echo on\nRequest echoing is on\n\n[BaseUrl]/api/values> set header Accept application/json\n\n[BaseUrl]/api/values> get\nRequest to [BaseUrl]...\n\nGET /api/values HTTP/1.1\nAccept: application/json\nUser-Agent: HTTP-REPL\n\n\nResponse from [BaseUrl]...\n\nHTTP/1.1 200 OK\nContent-Type: application/json; charset=utf-8\nDate: [Date]\nServer: Kestrel\nTransfer-Encoding: chunked\n\n[\n  \"\"value1\"\",\n  \"\"value2\"\"\n]\n\n\n[BaseUrl]/api/values>\", null);\n\n            Assert.Equal(expected, output);\n        }\n\n        [Fact]\n        public async Task WithEmptyValue_ClearsHeader()\n        {\n            string scriptText = $@\"connect {_serverConfig.BaseAddress}\ncd api/values\necho on\nset header User-Agent\nget\";\n\n            string output = await RunTestScript(scriptText, _serverConfig.BaseAddress);\n\n            string expected = NormalizeOutput(@\"(Disconnected)> connect [BaseUrl]\nUsing a base address of [BaseUrl]/\nUsing OpenAPI description at [BaseUrl]/swagger/v1/swagger.json\nFor detailed tool info, see https://aka.ms/http-repl-doc\n\n[BaseUrl]/> cd api/values\n/api/values    [GET|POST]\n\n[BaseUrl]/api/values> echo on\nRequest echoing is on\n\n[BaseUrl]/api/values> set header User-Agent\n\n[BaseUrl]/api/values> get\nRequest to [BaseUrl]...\n\nGET /api/values HTTP/1.1\n\n\nResponse from [BaseUrl]...\n\nHTTP/1.1 200 OK\nContent-Type: application/json; charset=utf-8\nDate: [Date]\nServer: Kestrel\nTransfer-Encoding: chunked\n\n[\n  \"\"value1\"\",\n  \"\"value2\"\"\n]\n\n\n[BaseUrl]/api/values>\", null);\n\n            Assert.Equal(expected, output);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/Microsoft.HttpRepl.IntegrationTests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>$(TestProjectTargetFramework)</TargetFramework>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <FrameworkReference Include=\"Microsoft.AspNetCore.App\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Moq\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"Newtonsoft.Json\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"Swashbuckle.AspNetCore\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"System.Net.Http\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"$(RepoSource)\\Microsoft.HttpRepl\\Microsoft.HttpRepl.csproj\" />\n    <ProjectReference Include=\"$(RepoTest)\\Microsoft.HttpRepl.Fakes\\Microsoft.HttpRepl.Fakes.csproj\" />\n    <ProjectReference Include=\"$(RepoSource)\\Microsoft.Repl\\Microsoft.Repl.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/SampleApi/Controllers/ValuesController.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.SampleApi.Controllers\n{\n    [Route(\"api/[controller]\")]\n    [ApiController]\n    public class ValuesController : ControllerBase\n    {\n        // GET api/values\n        [HttpGet]\n        public ActionResult<IEnumerable<string>> Get()\n        {\n            return new string[] { \"value1\", \"value2\" };\n        }\n\n        // GET api/values/5\n        [HttpGet(\"{id}\")]\n        public ActionResult<string> Get([FromQuery] int id)\n        {\n            return \"value\";\n        }\n\n        // POST api/values\n        [HttpPost]\n        public void Post([FromBody] string value)\n        {\n        }\n\n        // PUT api/values/5\n        [HttpPut(\"{id}\")]\n        public void Put(int id, [FromBody] string value)\n        {\n        }\n\n        // DELETE api/values/5\n        [HttpDelete(\"{id}\")]\n        public void Delete(int id)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/SampleApi/SampleApiServer.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.txt file in the project root for more information.\n\nusing Microsoft.AspNetCore;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\nusing Microsoft.OpenApi.Models;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.SampleApi\n{\n    public class SampleApiServer\n    {\n        private readonly IWebHost _Host;\n        public SampleApiServer(SampleApiServerConfig config)\n        {\n            _Host = WebHost.CreateDefaultBuilder()\n                           .UseKestrel(options =>\n                           {\n                               options.ListenLocalhost(config.Port.Value, (listenOptions) =>\n                               {\n                                   listenOptions.DisableAltSvcHeader = true;\n                               });\n                           })\n                           .ConfigureServices(services =>\n                           {\n                               services.AddControllers();\n                               if (config.EnableSwagger)\n                               {\n                                   services.AddSwaggerGen(c =>\n                                   {\n                                       c.SwaggerDoc(\"v1\", new OpenApiInfo { Title = \"My API\", Version = \"v1\" });\n                                   });\n                               }\n                           })\n                           .Configure(app =>\n                           {\n                               app.UseDeveloperExceptionPage();\n\n                               app.UseRouting();\n\n                               app.UseEndpoints(endpoints =>\n                               {\n                                   endpoints.MapControllers();\n                               });\n\n                               if (config.EnableSwagger)\n                               {\n                                   app.UseSwagger();\n                               }\n                           })\n                           .Build();\n        }\n\n        public void Start()\n        {\n            _Host.RunAsync();\n        }\n\n        public void Stop()\n        {\n            _Host.StopAsync();\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/SampleApi/SampleApiServerConfig.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.ObjectModel;\nusing System.Net;\nusing System.Net.Sockets;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Http;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.SampleApi\n{\n    public class SampleApiServerConfig\n    {\n        public string BaseAddress => $\"http://localhost:{Port}\";\n        public Lazy<int> Port { get; set; } = new Lazy<int>(() => FindFreeTcpPort());\n\n        /// <summary>\n        /// Turns Swagger on or off for the SampleApiServer instance.\n        /// </summary>\n        public bool EnableSwagger { get; set; } = true;\n\n        public Collection<SampleApiServerRoute> Routes { get; } = new Collection<SampleApiServerRoute>();\n\n        private static int FindFreeTcpPort()\n        {\n            TcpListener l = new TcpListener(IPAddress.Loopback, 0);\n            l.Start();\n            int port = ((IPEndPoint)l.LocalEndpoint).Port;\n            l.Stop();\n            return port;\n        }\n    }\n\n    public abstract class SampleApiServerRoute\n    {\n        public string Verb { get; set; } = \"GET\";\n        public string Route { get; set; }\n\n        public abstract Task Execute(HttpContext context);\n    }\n\n    public sealed class StaticSampleApiServerRoute : SampleApiServerRoute\n    {\n        public string Result { get; set; }\n        public StaticSampleApiServerRoute(string verb, string route, string result)\n        {\n            Verb = verb;\n            Route = route;\n            Result = result;\n        }\n\n        public async override Task Execute(HttpContext context)\n        {\n            await context.Response.WriteAsync(Result);\n        }\n    }\n\n    public sealed class DynamicSampleApiServerRoute : SampleApiServerRoute\n    {\n        public Func<HttpContext, Task> ResultFunction { get; set; }\n        public DynamicSampleApiServerRoute(string verb, string route, Func<HttpContext, Task> resultFunction)\n        {\n            Verb = verb;\n            Route = route;\n            ResultFunction = resultFunction;\n        }\n\n        public async override Task Execute(HttpContext context)\n        {\n            await ResultFunction(context);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.IntegrationTests/Utilities/TestScript.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.txt file in the project root for more information.\n\nusing System;\nusing System.IO;\n\nnamespace Microsoft.HttpRepl.IntegrationTests.Utilities\n{\n    public class TestScript : IDisposable\n    {\n        public string FilePath { get; }\n\n        public TestScript(string content)\n        {\n            FilePath = Path.GetTempFileName();\n            File.WriteAllText(FilePath, content);\n        }\n\n        public void Dispose()\n        {\n            if(File.Exists(FilePath))\n            {\n                File.Delete(FilePath);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/AddQueryParamCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class AddQueryParamCommandTests : CommandTestsBase\n    {\n        [Fact]\n        public void CanHandle_WithParseResultSectionsLessThanTwo_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"add\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            AddQueryParamCommand addQueryParamCommand= new AddQueryParamCommand(new NullTelemetry());\n            bool? result = addQueryParamCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithFirstParseResultSectionNotEqualToName_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"test query-param name\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            AddQueryParamCommand addQueryParamCommand = new AddQueryParamCommand(new NullTelemetry());\n            bool? result = addQueryParamCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithSecondParseResultSectionNotEqualToSubCommand_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"add base name\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            AddQueryParamCommand addQueryParamCommand = new AddQueryParamCommand(new NullTelemetry());\n            bool? result = addQueryParamCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithValidInput_ReturnsTrue()\n        {\n            ArrangeInputs(parseResultSections: \"add query-param name value\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            AddQueryParamCommand setQueryParamCommand = new AddQueryParamCommand(new NullTelemetry());\n            bool? result = setQueryParamCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.True(result);\n        }\n\n        [Fact]\n        public void GetHelpDetails_ReturnsHelpDetails()\n        {\n            ArrangeInputs(parseResultSections: \"add query-param test\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            string expected = \"\\u001b[1mUsage: \\u001b[39madd query-param {name} [value]\" + Environment.NewLine\n                + Environment.NewLine + \"Adds a key and value pair to the query string. \" +\n                \"The key and value will be UrlEncoded. Multiple values may be mapped to the same key.\" + Environment.NewLine;\n\n            AddQueryParamCommand addQueryParamCommand = new AddQueryParamCommand(new NullTelemetry());\n            string result = addQueryParamCommand.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_ValidCommandInvalidInput_CommandOutput()\n        {\n            ArrangeInputs(parseResultSections: \"add query-param test\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            AddQueryParamCommand addQueryParamCommand = new AddQueryParamCommand(new NullTelemetry());\n            await addQueryParamCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedOutput = \"The add query-param command key: test is missing a value. \" +\n                \"Please try again with a valid key value pair\";\n            Assert.Equal(shellState.Output.Last(), expectedOutput);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithMultipleValuesMapped()\n        {\n            ArrangeInputs(parseResultSections: \"add query-param name value1 name value2\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            AddQueryParamCommand addQueryParamCommand = new AddQueryParamCommand(new NullTelemetry());\n            await addQueryParamCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Dictionary<string, IEnumerable<string>> queryParam = httpState.QueryParam;\n            Assert.Single(httpState.QueryParam);\n            Assert.True(queryParam.ContainsKey(\"name\"));\n\n            queryParam.TryGetValue(\"name\", out IEnumerable<string> nameHeaderValues);\n            Assert.Contains(\"value1\", nameHeaderValues);\n            Assert.Contains(\"value2\", nameHeaderValues);\n\n            ArrangeInputs(parseResultSections: \"add query-param name value3\",\n                 out MockedShellState shellStateTwo,\n                 out HttpState httpStateTwo,\n                 out ICoreParseResult parseResultTwo);\n\n            await addQueryParamCommand.ExecuteAsync(shellStateTwo, httpState, parseResultTwo, CancellationToken.None);\n\n            queryParam = httpState.QueryParam;\n            Assert.Single(httpState.QueryParam);\n            Assert.True(queryParam.ContainsKey(\"name\"));\n\n            queryParam.TryGetValue(\"name\", out IEnumerable<string> nameHeaderValuesTwo);\n            Assert.Contains(\"value3\", nameHeaderValuesTwo);     \n        }\n\n        [Fact]\n        public async Task ExecuteAsync_ValidCommandWithSpace()\n        {\n            ArrangeInputs(parseResultSections: \"add query-param test \",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            AddQueryParamCommand addQueryParamCommand = new AddQueryParamCommand(new NullTelemetry());\n            await addQueryParamCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Dictionary<string, IEnumerable<string>> queryParam = httpState.QueryParam;\n            Assert.Single(httpState.QueryParam);\n            Assert.True(queryParam.ContainsKey(\"test\"));\n            queryParam.TryGetValue(\"test\", out IEnumerable<string> nameHeaderValue);\n            Assert.Contains(\"\", nameHeaderValue);\n        }\n\n\n        [Fact]\n        public async Task ExecuteAsync__SendsTelemetryWithHashedHeaderName()\n        {\n            ArrangeInputs(parseResultSections: \"add query-param name value\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            TelemetryCollector telemetry = new TelemetryCollector();\n\n            AddQueryParamCommand addQueryParamCommand = new AddQueryParamCommand(telemetry);\n            await addQueryParamCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(telemetry.Telemetry);\n            TelemetryCollector.CollectedTelemetry collectedTelemetry = telemetry.Telemetry[0];\n            Assert.Equal(\"AddQueryParam\", collectedTelemetry.EventName);\n            Assert.Equal(Sha256Hasher.Hash(\"name\"), collectedTelemetry.Properties[\"QueryParamKey\"]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[\"IsValueEmpty\"]);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/ChangeDirectoryCommandTests.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.txt file in the project root for more information.\n\nusing System.Net.Http;\nusing System.Threading;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.OpenApi;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.UserProfile;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class ChangeDirectoryCommandTests\n    {\n        [Fact]\n        public void ExecuteAsync_UnknownEndpoint_DisplaysWarning()\n        {\n            ChangeDirectoryCommand command = new ChangeDirectoryCommand();\n\n            Setup(commandText: \"cd NotAnEndpoint\", out MockedShellState mockedShellState, out HttpState httpState, out ICoreParseResult parseResult);\n\n            ApiDefinition apiDefinition = new ApiDefinition()\n            {\n                DirectoryStructure = new DirectoryStructure(null)\n            };\n            httpState.ApiDefinition = apiDefinition;\n\n            string expectedFirstLine = string.Format(Resources.Strings.ChangeDirectoryCommand_Warning_UnknownEndpoint, \"/NotAnEndpoint\").SetColor(httpState.WarningColor);\n            string expectedSecondLine = \"/NotAnEndpoint    []\";\n\n            command.ExecuteAsync(mockedShellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(2, mockedShellState.Output.Count);\n            Assert.Equal(expectedFirstLine, mockedShellState.Output[0]);\n            Assert.Equal(expectedSecondLine, mockedShellState.Output[1]);\n        }\n\n        [Fact]\n        public void ExecuteAsync_KnownEndpointWithRequestMethods_NoWarning()\n        {\n            ChangeDirectoryCommand command = new ChangeDirectoryCommand();\n\n            Setup(commandText: \"cd AnEndpoint\", out MockedShellState mockedShellState, out HttpState httpState, out ICoreParseResult parseResult);\n\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            DirectoryStructure childDirectory = directoryStructure.DeclareDirectory(\"AnEndpoint\");\n            RequestInfo childRequestInfo = new RequestInfo();\n            childRequestInfo.AddMethod(\"GET\");\n            childDirectory.RequestInfo = childRequestInfo;\n            ApiDefinition apiDefinition = new ApiDefinition()\n            {\n                DirectoryStructure = directoryStructure\n            };\n            httpState.ApiDefinition = apiDefinition;\n\n            string expectedOutput = \"/AnEndpoint    [GET]\";\n\n            command.ExecuteAsync(mockedShellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(mockedShellState.Output);\n            Assert.Equal(expectedOutput, mockedShellState.Output[0]);\n        }\n\n        [Fact]\n        public void ExecuteAsync_KnownEndpointWithSubdirectory_NoWarning()\n        {\n            ChangeDirectoryCommand command = new ChangeDirectoryCommand();\n\n            Setup(commandText: \"cd AnEndpoint\", out MockedShellState mockedShellState, out HttpState httpState, out ICoreParseResult parseResult);\n\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            DirectoryStructure childDirectory = directoryStructure.DeclareDirectory(\"AnEndpoint\");\n            DirectoryStructure grandchildDirectory = childDirectory.DeclareDirectory(\"AnotherEndpoint\");\n            ApiDefinition apiDefinition = new ApiDefinition()\n            {\n                DirectoryStructure = directoryStructure\n            };\n            httpState.ApiDefinition = apiDefinition;\n\n            string expectedOutput = \"/AnEndpoint    []\";\n\n            command.ExecuteAsync(mockedShellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(mockedShellState.Output);\n            Assert.Equal(expectedOutput, mockedShellState.Output[0]);\n        }\n\n        private void Setup(string commandText, out MockedShellState mockedShellState, out HttpState httpState, out ICoreParseResult parseResult)\n        {\n            mockedShellState = new MockedShellState();\n            IFileSystem fileSystem = new RealFileSystem();\n            IUserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            IPreferences preferences = new UserFolderPreferences(fileSystem, userProfileDirectoryProvider, null);\n            parseResult = CoreParseResultHelper.Create(commandText);\n            HttpClient httpClient = new HttpClient();\n\n            httpState = new HttpState(preferences, httpClient);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/ClearCommandTests.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class ClearCommandTests : CommandTestsBase\n    {\n        [Theory]\n        [InlineData(\"clear\", true)]\n        [InlineData(\"cls\", true)]\n        [InlineData(\"cd\", null)]\n        [InlineData(\"clearing\", null)]\n        public void CanHandle_ReturnsCorrectResult(string command, bool? expectedResult)\n        {\n            ArrangeInputs(parseResultSections: command,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult);\n\n            ClearCommand clearCommand = new ClearCommand();\n\n            bool? result = clearCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Equal(expectedResult, result);\n        }\n\n        [Fact]\n        public void Suggest_Cl_ReturnsBoth()\n        {\n            ArrangeInputs(parseResultSections: \"cl\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult);\n\n            ClearCommand clearCommand = new ClearCommand();\n\n            IEnumerable<string> result = clearCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.NotNull(result);\n\n            List<string> resultList = result.ToList();\n\n            Assert.Equal(2, resultList.Count);\n            Assert.Equal(\"clear\", resultList[0]);\n            Assert.Equal(\"cls\", resultList[1]);\n        }\n\n        [Fact]\n        public void Suggest_Cle_ReturnsClear()\n        {\n            ArrangeInputs(parseResultSections: \"cle\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult);\n\n            ClearCommand clearCommand = new ClearCommand();\n\n            IEnumerable<string> result = clearCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.NotNull(result);\n\n            List<string> resultList = result.ToList();\n\n            Assert.Single(resultList);\n            Assert.Equal(\"clear\", resultList[0]);\n        }\n\n        [Fact]\n        public void Suggest_Cls_ReturnsCls()\n        {\n            ArrangeInputs(parseResultSections: \"cls\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult);\n\n            ClearCommand clearCommand = new ClearCommand();\n\n            IEnumerable<string> result = clearCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.NotNull(result);\n\n            List<string> resultList = result.ToList();\n\n            Assert.Single(resultList);\n            Assert.Equal(\"cls\", resultList[0]);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_CallsConsoleManagerClear()\n        {\n            HttpState httpState = GetHttpState(out _, out _);\n            ICoreParseResult parseResult = CreateCoreParseResult(\"clear\");\n            DefaultCommandDispatcher<HttpState> dispatcher = DefaultCommandDispatcher.Create((ss) => { }, httpState);\n            LoggingConsoleManagerDecorator consoleManager = new LoggingConsoleManagerDecorator(new NullConsoleManager());\n            IShellState shellState = new ShellState(dispatcher, consoleManager: consoleManager);\n\n            ClearCommand clearCommand = new ClearCommand();\n\n            await clearCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.True(consoleManager.WasClearCalled);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_CallsDispatcherOnReady()\n        {\n            bool wasOnReadyCalled = false;\n\n            HttpState httpState = GetHttpState(out _, out _);\n            ICoreParseResult parseResult = CreateCoreParseResult(\"clear\");\n            DefaultCommandDispatcher<HttpState> dispatcher = DefaultCommandDispatcher.Create((ss) => wasOnReadyCalled = true, httpState);\n            IConsoleManager consoleManager = new LoggingConsoleManagerDecorator(new NullConsoleManager());\n            IShellState shellState = new ShellState(dispatcher, consoleManager: consoleManager);\n\n            ClearCommand clearCommand = new ClearCommand();\n\n            await clearCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.True(wasOnReadyCalled);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/ClearQueryParamCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class ClearQueryParamCommandTests: CommandTestsBase\n    {        \n        [Fact]\n        public void CanHandle_WithFirstParseResultSectionNotEqualToName_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"test query-param name\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            ClearQueryParamCommand clearQueryParamCommand = new ClearQueryParamCommand(new NullTelemetry());\n            bool? result = clearQueryParamCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithSecondParseResultSectionNotEqualToSubCommand_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"set base name\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            ClearQueryParamCommand clearQueryParamCommand = new ClearQueryParamCommand(new NullTelemetry());\n            bool? result = clearQueryParamCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithValidInput_ReturnsTrue()\n        {\n            ArrangeInputs(parseResultSections: \"clear query-param\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            ClearQueryParamCommand clearQueryParamCommand = new ClearQueryParamCommand(new NullTelemetry());\n            bool? result = clearQueryParamCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.True(result);\n        }\n\n        [Fact]\n        public void GetHelpSummary_ReturnsDescription()\n        {\n            ArrangeInputs(parseResultSections: string.Empty,\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult _);\n\n            ClearQueryParamCommand clearQueryParamCommand = new ClearQueryParamCommand(new NullTelemetry());\n            string result = clearQueryParamCommand.GetHelpSummary(shellState, httpState);\n\n            Assert.Equal(ClearQueryParamCommand.Description, result);\n        }\n\n        [Fact]\n        public void GetHelpDetails_ReturnsHelpDetails()\n        {\n            ArrangeInputs(parseResultSections: \"clear query-param\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            string expected = \"\\u001b[1mUsage: \\u001b[39mclear query-param\" + Environment.NewLine + Environment.NewLine + \"Clears the query string of all key and values\" + Environment.NewLine;\n\n            ClearQueryParamCommand clearQueryParamCommand = new ClearQueryParamCommand(new NullTelemetry());\n            string result = clearQueryParamCommand.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Fact]\n        public async Task ClearQueryParamCommandWorkingAsync()\n        {\n            ArrangeInputs(parseResultSections: \"add query-param limit 5\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            AddQueryParamCommand addQueryParamCommand = new AddQueryParamCommand(new NullTelemetry());\n            await addQueryParamCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Dictionary<string, IEnumerable<string>> queryParamAfterAdd = httpState.QueryParam;\n            Assert.True(queryParamAfterAdd.ContainsKey(\"limit\"));\n\n            ClearQueryParamCommand clearQueryParamCommand = new ClearQueryParamCommand(new NullTelemetry());\n            await clearQueryParamCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Dictionary<string, IEnumerable<string>> queryParamAfterClear = httpState.QueryParam;\n            Assert.True(queryParamAfterClear.ContainsKey(\"limit\"));         \n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/CommandTestsBase.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Moq;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class CommandTestsBase\n    {\n        protected static void ArrangeInputs(string parseResultSections,\n            out MockedShellState shellState,\n            out HttpState httpState,\n            out ICoreParseResult parseResult,\n            string baseAddress = \"\",\n            int caretPosition = -1,\n            string responseContent = \"\")\n        {\n            parseResult = CoreParseResultHelper.Create(parseResultSections, caretPosition);\n            shellState = new MockedShellState();\n            IDictionary<string, string> urlsWithResponse = new Dictionary<string, string>();\n            urlsWithResponse.Add(baseAddress, responseContent);\n\n            httpState = GetHttpState(out _, out _, urlsWithResponse: urlsWithResponse);\n        }\n\n        protected void ArrangeInputs(string commandText,\n            string baseAddress,\n            string path,\n            IDictionary<string, string> urlsWithResponse,\n            out MockedShellState shellState,\n            out HttpState httpState,\n            out ICoreParseResult parseResult,\n            out MockedFileSystem fileSystem,\n            out IPreferences preferences,\n            string header = \"\",\n            bool readBodyFromFile = false,\n            string fileContents = \"\",\n            string contentType = \"\")\n        {\n            parseResult = CoreParseResultHelper.Create(commandText);\n            shellState = new MockedShellState();\n\n            httpState = GetHttpState(out fileSystem,\n                out preferences,\n                baseAddress,\n                header,\n                path,\n                urlsWithResponse,\n                readBodyFromFile,\n                fileContents,\n                contentType);\n        }\n\n        protected void ArrangeInputsWithOptional(string commandText,\n            string baseAddress,\n            string path,\n            IDictionary<string, string> urlsWithResponse,\n            out MockedShellState shellState,\n            out HttpState httpState,\n            out ICoreParseResult parseResult,\n            ref MockedFileSystem fileSystem,\n            ref IPreferences preferences,\n            string header = \"\",\n            bool readBodyFromFile = false,\n            string fileContents = \"\",\n            string contentType = \"\")\n        {\n            parseResult = CoreParseResultHelper.Create(commandText);\n            shellState = new MockedShellState();\n\n            httpState = GetHttpStateWithOptional(ref fileSystem,\n                ref preferences,\n                baseAddress,\n                header,\n                path,\n                urlsWithResponse,\n                readBodyFromFile,\n                fileContents,\n                contentType);\n        }\n\n        protected static void VerifyErrorMessageWasWrittenToConsoleManagerError(IShellState shellState)\n        {\n            Mock<IWritable> error = Mock.Get(shellState.ConsoleManager.Error);\n\n            error.Verify(s => s.WriteLine(It.IsAny<string>()), Times.Once);\n        }\n\n        protected static HttpState GetHttpStateWithOptional(ref MockedFileSystem fileSystem,\n            ref IPreferences preferences,\n            string baseAddress = \"\",\n            string header = \"\",\n            string path = \"\",\n            IDictionary<string, string> urlsWithResponse = null,\n            bool readFromFile = false,\n            string fileContents = \"\",\n            string contentType = \"\")\n        {\n            HttpResponseMessage responseMessage = new HttpResponseMessage();\n            responseMessage.Content = new MockHttpContent(string.Empty);\n            MockHttpMessageHandler messageHandler = new MockHttpMessageHandler(urlsWithResponse, header, readFromFile, fileContents, contentType);\n            HttpClient httpClient = new HttpClient(messageHandler);\n            fileSystem ??= new MockedFileSystem();\n            preferences ??= new NullPreferences();\n\n            HttpState httpState = new HttpState(preferences, httpClient);\n\n            if (!string.IsNullOrWhiteSpace(baseAddress))\n            {\n                httpState.BaseAddress = new Uri(baseAddress);\n            }\n            if (!string.IsNullOrWhiteSpace(path))\n            {\n                httpState.BaseAddress = new Uri(baseAddress);\n\n                string[] pathParts = path.Split('/');\n\n                foreach (string pathPart in pathParts)\n                {\n                    httpState.PathSections.Push(pathPart);\n                }\n            }\n\n            return httpState;\n        }\n\n        protected static HttpState GetHttpState(out MockedFileSystem fileSystem,\n            out IPreferences preferences,\n            string baseAddress = \"\",\n            string header = \"\",\n            string path = \"\",\n            IDictionary<string, string> urlsWithResponse = null,\n            bool readFromFile = false,\n            string fileContents = \"\",\n            string contentType = \"\")\n        {\n            fileSystem = new MockedFileSystem();\n            preferences = new NullPreferences();\n\n            return GetHttpStateWithOptional(ref fileSystem,\n                ref preferences,\n                baseAddress,\n                header,\n                path,\n                urlsWithResponse,\n                readFromFile,\n                fileContents,\n                contentType);\n        }\n\n        protected ICoreParseResult CreateCoreParseResult(string commandText)\n        {\n            return CoreParseResultHelper.Create(commandText);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/ConnectCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.UserProfile;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class ConnectCommandTests : CommandTestsBase\n    {\n        [Fact]\n        public async Task ExecuteAsync_WithNothingSpecified_ShowsError()\n        {\n            ArrangeInputs(\"connect\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(Resources.Strings.ConnectCommand_Error_NothingSpecified, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithInvalidRoot_ShowsError()\n        {\n            ArrangeInputs(\"connect example.com\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(Resources.Strings.ConnectCommand_Error_RootAddressNotValid, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoRootAndRelativeBase_ShowsError()\n        {\n            ArrangeInputs(\"connect --base /v1\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(Resources.Strings.ConnectCommand_Error_NoRootNoAbsoluteBase, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoRootAndRelativeSwagger_ShowsError()\n        {\n            ArrangeInputs(\"connect --swagger /v1/swagger.json\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(Resources.Strings.ConnectCommand_Error_NoRootNoAbsoluteSwagger, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoRootAndRelativeOpenApi_ShowsError()\n        {\n            ArrangeInputs(\"connect --openapi /v1/openapi.json\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(Resources.Strings.ConnectCommand_Error_NoRootNoAbsoluteSwagger, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithRootAndNoBase_SetsBaseToRoot()\n        {\n            string rootAddress = \"https://localhost/\";\n            ArrangeInputs($\"connect {rootAddress}\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences,\n                          fileContents: \"\");\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(rootAddress, httpState.BaseAddress?.ToString());\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithJustRoot_SetsBaseAndDefinition()\n        {\n            string rootAddress = \"https://localhost/\";\n            string swaggerAddress = \"https://localhost/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v2 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/api/Values\"\": {\n      \"\"post\"\": {\n      }\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect {rootAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(rootAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithJustBase_FindsSwaggerSetsDefinition()\n        {\n            string baseAddress = \"https://localhost/\";\n            string swaggerAddress = \"https://localhost/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v2 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/api/Values\"\": {\n      \"\"post\"\": {\n      }\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect --base {baseAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(baseAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithJustSwagger_SetsBaseAndDefinition()\n        {\n            string baseAddress = \"https://localhost/\";\n            string swaggerAddress = \"https://localhost/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"\" + baseAddress + @\"\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect --swagger {swaggerAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(baseAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithBaseAndSwagger_SetsBaseAndDefinitionIgnoresSwaggerBase()\n        {\n            string baseAddress = \"https://localhost/\";\n            string swaggerAddress = \"https://localhost/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"https://example.com/\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect --base {baseAddress} --swagger {swaggerAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(baseAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithRootAndBase_FindsSwaggerFromRoot()\n        {\n            string rootAddress = \"https://localhost/\";\n            string baseAddress = \"https://localhost/v2/\";\n            string swaggerAddress = \"https://localhost/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"https://example.com/\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect {rootAddress} --base {baseAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(baseAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithRootAndBase_FindsSwaggerFromBase()\n        {\n            string rootAddress = \"https://localhost/\";\n            string baseAddress = \"https://localhost/v2/\";\n            string swaggerAddress = \"https://localhost/v2/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"https://example.com/\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect {rootAddress} --base {baseAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(baseAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithRootAndBase_FindsOpenApiFromRoot()\n        {\n            string rootAddress = \"https://localhost/\";\n            string baseAddress = \"https://localhost/v2/\";\n            string swaggerAddress = \"https://localhost/openapi.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"https://example.com/\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect {rootAddress} --base {baseAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(baseAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithRootAndBase_FindsOpenApiFromBase()\n        {\n            string rootAddress = \"https://localhost/\";\n            string baseAddress = \"https://localhost/v2/\";\n            string swaggerAddress = \"https://localhost/v2/openapi.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"https://example.com/\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect {rootAddress} --base {baseAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(baseAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithRootAndSwaggerWithoutBase_SetsBaseToRoot()\n        {\n            string rootAddress = \"https://localhost/\";\n            string swaggerAddress = \"https://localhost/v2/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect {rootAddress} --swagger {swaggerAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(rootAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithRootAndSwaggerWithBase_SetsBaseToSwaggerBase()\n        {\n            string rootAddress = \"https://localhost/\";\n            string baseAddress = \"https://localhost/v2/\";\n            string swaggerAddress = \"https://localhost/v2/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"\" + baseAddress + @\"\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect {rootAddress} --swagger {swaggerAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Equal(baseAddress, httpState.BaseAddress.ToString());\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Equal(swaggerAddress, httpState.SwaggerEndpoint.ToString());\n            Assert.NotNull(httpState.ApiDefinition);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_SwaggerOnlyWithNoBase_ShowsWarning()\n        {\n            string swaggerAddress = \"https://localhost/v2/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect --swagger {swaggerAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Null(httpState.BaseAddress);\n            Assert.Contains(Resources.Strings.ConnectCommand_Status_NoBase, shellState.Output, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_RootOnlyNoSwaggerFound_ShowsWarning()\n        {\n            string rootAddress = \"https://localhost/\";\n\n            ArrangeInputs(commandText: $\"connect {rootAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Null(httpState.SwaggerEndpoint);\n            Assert.Contains(Resources.Strings.ConnectCommand_Status_NoSwagger, shellState.Output, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_SwaggerOnlyWithBase_ShowsBaseAndSwaggerResult()\n        {\n            string baseAddress = \"https://localhost/v2/\";\n            string swaggerAddress = \"https://localhost/v2/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"\" + baseAddress + @\"\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n            ArrangeInputs(commandText: $\"connect --swagger {swaggerAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { swaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.NotNull(httpState.BaseAddress);\n            Assert.Contains(string.Format(Resources.Strings.ConnectCommand_Status_Base, httpState.BaseAddress), shellState.Output, StringComparer.Ordinal);\n            Assert.NotNull(httpState.SwaggerEndpoint);\n            Assert.Contains(string.Format(Resources.Strings.ConnectCommand_Status_Swagger, httpState.SwaggerEndpoint), shellState.Output, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_RootOnlyWithVerbose_OutputContainsAttempts()\n        {\n            string rootAddress = \"https://localhost/v2\";\n\n            ArrangeInputs(commandText: $\"connect {rootAddress} --verbose\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>(),\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Contains(Resources.Strings.ApiConnection_Logging_Parsing + Resources.Strings.ApiConnection_Logging_Failed, shellState.Output, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_RootOnlyWithoutVerbose_OutputDoesNotContainAttempts()\n        {\n            string rootAddress = \"https://localhost/v2\";\n\n            ArrangeInputs(commandText: $\"connect {rootAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>(),\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.DoesNotContain(Resources.Strings.ApiConnection_Logging_Parsing + Resources.Strings.ApiConnection_Logging_Failed, shellState.Output, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_SwaggerOnlyWithoutVerbose_OutputContainsAttempts()\n        {\n            string openApiDescriptionUrl = \"https://localhost/v2/swagger.json\";\n\n            ArrangeInputs(commandText: $\"connect --openapi {openApiDescriptionUrl}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>(),\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Contains(Resources.Strings.ApiConnection_Logging_Parsing + Resources.Strings.ApiConnection_Logging_Failed, shellState.Output, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_RootWithSwaggerSuffix_FixesBase()\n        {\n            string rootAddress = \"https://localhost:44368/swagger\";\n            string expectedBaseAddress = \"https://localhost:44368/\";\n            string expectedSwaggerAddress = \"https://localhost:44368/swagger/v1/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/WeatherForecast\"\": {\n    }\n  }\n}\";\n\n            ArrangeInputs(commandText: $\"connect {rootAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { expectedSwaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Contains(string.Format(Resources.Strings.ConnectCommand_Status_Base, expectedBaseAddress), shellState.Output, StringComparer.Ordinal);\n            Assert.Contains(string.Format(Resources.Strings.ConnectCommand_Status_Swagger, expectedSwaggerAddress), shellState.Output, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_RootWithSwaggerSuffixAndOverride_DoesNotFixBase()\n        {\n            string rootAddress = \"https://localhost:44368/swagger\";\n            string expectedBaseAddress = rootAddress + \"/\";\n            string expectedSwaggerAddress = \"https://localhost:44368/swagger/v1/swagger.json\";\n            string swaggerContent = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/WeatherForecast\"\": {\n    }\n  }\n}\";\n\n            MockedFileSystem fileSystem = new MockedFileSystem();\n            UserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            IPreferences preferences = new UserFolderPreferences(fileSystem,\n                                                                 userProfileDirectoryProvider,\n                                                                 new Dictionary<string, string> { { WellKnownPreference.ConnectCommandSkipRootFix, \"true\"}});\n\n            ArrangeInputsWithOptional(commandText: $\"connect {rootAddress}\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: new Dictionary<string, string>() { { expectedSwaggerAddress, swaggerContent } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          ref fileSystem,\n                          ref preferences);\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Contains(string.Format(Resources.Strings.ConnectCommand_Status_Base, expectedBaseAddress), shellState.Output, StringComparer.Ordinal);\n            Assert.Contains(string.Format(Resources.Strings.ConnectCommand_Status_Swagger, expectedSwaggerAddress), shellState.Output, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithOnlyRoot_SendsTelemetry()\n        {\n            string rootAddress = \"https://localhost/\";\n            ArrangeInputs($\"connect {rootAddress}\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences,\n                          fileContents: \"\");\n\n            TelemetryCollector telemetry = new TelemetryCollector();\n\n            ConnectCommand connectCommand = new ConnectCommand(preferences, telemetry);\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(telemetry.Telemetry);\n            TelemetryCollector.CollectedTelemetry collectedTelemetry = telemetry.Telemetry[0];\n            Assert.Equal(\"connect\", collectedTelemetry.EventName, ignoreCase: true);\n            Assert.Equal(\"True\", collectedTelemetry.Properties[\"RootSpecified\"]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[\"BaseSpecified\"]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[\"OpenApiSpecified\"]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[\"OpenApiFound\"]);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithoutPersistHeaders_DoesNotPersistNonDefaultHeaders()\n        {\n            string rootAddress = \"https://localhost/\";\n            ArrangeInputs($\"connect {rootAddress}\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences,\n                          fileContents: \"\");\n\n            httpState.Headers[\"TestHeaderName\"] = new[] { \"TestHeaderValue\" };\n\n            ConnectCommand connectCommand = new(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(httpState.Headers);\n            Assert.True(httpState.Headers.ContainsKey(\"User-Agent\"));\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithoutPersistPaths_DoesNotPersistPaths()\n        {\n            string rootAddress = \"https://localhost/\";\n            ArrangeInputs($\"connect {rootAddress}\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences,\n                          fileContents: \"\");\n\n            httpState.PathSections.Push(\"dir1\");\n\n            ConnectCommand connectCommand = new(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Empty(httpState.PathSections);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithPersistHeaders_PersistsHeaders()\n        {\n            string expectedHeaderName = \"TestHeaderName\";\n            string expectedHeaderValue = \"TestHeaderValue\";\n            string rootAddress = \"https://localhost/\";\n            ArrangeInputs($\"connect {rootAddress} --persist-headers\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences,\n                          fileContents: \"\");\n\n            httpState.Headers[expectedHeaderName] = new[] { expectedHeaderValue };\n\n            ConnectCommand connectCommand = new(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.True(httpState.Headers.ContainsKey(expectedHeaderName));\n            Assert.Equal(expectedHeaderValue, httpState.Headers[expectedHeaderName].Single());\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithPersistPaths_PersistsPaths()\n        {\n            string expectedPathSection = \"dir1\";\n            string rootAddress = \"https://localhost/\";\n            ArrangeInputs($\"connect {rootAddress} --persist-paths\",\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out IPreferences preferences,\n                          fileContents: \"\");\n\n            httpState.PathSections.Push(expectedPathSection);\n\n            ConnectCommand connectCommand = new(preferences, new NullTelemetry());\n\n            await connectCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(httpState.PathSections);\n            Assert.Equal(httpState.PathSections.Peek(), expectedPathSection);\n        }\n\n        private void ArrangeInputs(string commandText, out MockedShellState shellState, out HttpState httpState, out ICoreParseResult parseResult, out IPreferences preferences, string fileContents = null)\n        {\n            ArrangeInputs(commandText,\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out shellState,\n                          out httpState,\n                          out parseResult,\n                          out _,\n                          out preferences,\n                          readBodyFromFile: fileContents is object,\n                          fileContents: fileContents);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/CoreParseResultHelper.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.txt file in the project root for more information.\n\nusing System;\nusing Microsoft.Repl.Parsing;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    internal static class CoreParseResultHelper\n    {\n        public static ICoreParseResult Create(string commandText, int caretPosition = -1)\n        {\n            if (commandText == null)\n            {\n                throw new ArgumentNullException(nameof(commandText));\n            }\n\n            if (caretPosition == -1)\n            {\n                caretPosition = commandText.Length;\n            }\n\n            CoreParser coreParser = new CoreParser();\n            ICoreParseResult parseResult = coreParser.Parse(commandText, caretPosition);\n\n            return parseResult;\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/DeleteCommandsTests.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class DeleteCommandTests : CommandTestsBase\n    {\n        private string _baseAddress;\n        private string _path;\n        private IDictionary<string, string> _urlsWithResponse = new Dictionary<string, string>();\n\n        public DeleteCommandTests()\n        {\n            _baseAddress = \"http://localhost:5050/\";\n            _path = \"a/file/path.txt\";\n\n            _urlsWithResponse.Add(_baseAddress, \"Root delete received successfully.\");\n            _urlsWithResponse.Add(_baseAddress + _path, \"File path delete received successfully.\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoBasePath_VerifyError()\n        {\n            ArrangeInputs(commandText: \"DELETE\",\n                baseAddress: null,\n                path: null,\n                urlsWithResponse: null,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            string expectedErrorMessage = Strings.Error_NoBasePath.SetColor(httpState.ErrorColor);\n\n            DeleteCommand deleteCommand = new DeleteCommand(fileSystem, preferences, new NullTelemetry());\n            await deleteCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(expectedErrorMessage, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithMultipartRoute_VerifyOutput()\n        {\n            ArrangeInputs(commandText: \"DELETE\",\n                baseAddress: _baseAddress,\n                path: _path,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            DeleteCommand deleteCommand = new DeleteCommand(fileSystem, preferences, new NullTelemetry());\n            await deleteCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"File path delete received successfully.\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithOnlyBaseAddress_VerifyOutput()\n        {\n            ArrangeInputs(commandText: \"DELETE\",\n                baseAddress: _baseAddress,\n                path: null,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            DeleteCommand deleteCommand = new DeleteCommand(fileSystem, preferences, new NullTelemetry());\n            await deleteCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"Root delete received successfully.\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/EchoCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class EchoCommandTests : CommandTestsBase\n    {\n        [Theory]\n        [InlineData(\"echo ON\", true)]\n        [InlineData(\"echo on\", true)]\n        [InlineData(\"echo oN\", true)]\n        [InlineData(\"echo OFF\", true)]\n        [InlineData(\"echo off\", true)]\n        [InlineData(\"echo oFf\", true)]\n        [InlineData(\"echo no\", false)]\n        [InlineData(\"echo yes\", false)]\n        public void CanHandle(string commandText, bool expected)\n        {\n            ArrangeInputs(commandText, out MockedShellState shellState, out HttpState httpState, out ICoreParseResult parseResult);\n\n            EchoCommand echoCommand = new EchoCommand();\n\n            bool? result = echoCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Theory]\n        [InlineData(\"echo o\", \"on\", \"off\")]\n        [InlineData(\"echo O\", \"on\", \"off\")]\n        [InlineData(\"echo on\", \"on\")]\n        [InlineData(\"echo of\", \"off\")]\n        [InlineData(\"echo off\", \"off\")]\n        public void GetArgumentSuggestionsForText(string commandText, params string[] expectedResults)\n        {\n            ArrangeInputs(commandText, out MockedShellState shellState, out HttpState httpState, out ICoreParseResult parseResult);\n\n            EchoCommand echoCommand = new EchoCommand();\n\n            IEnumerable<string> result = echoCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.NotNull(result);\n\n            List<string> resultList = result.ToList();\n\n            Assert.Equal(expectedResults.Length, resultList.Count);\n\n            for (int index = 0; index < expectedResults.Length; index++)\n            {\n                Assert.Contains(expectedResults[index], resultList, StringComparer.OrdinalIgnoreCase);\n            }\n        }\n\n        [Fact]\n        public async Task PostCommand_WithEchoOn_OnlyPrintsRequestBodyOnce()\n        {\n            string baseAddress = \"https://localhost/\";\n            string path = \"values/5\";\n            string content = \"Test Post Body\";\n            ArrangeInputs(commandText: $\"POST --content \\\"{content}\\\"\",\n                baseAddress: baseAddress,\n                path: path,\n                urlsWithResponse: new Dictionary<string, string>() { { \"https://localhost/values/5\", \"\" } },\n                out var shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n            httpState.EchoRequest = true;\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            List<string> result = shellState.Output;\n\n            int countOfOccurrences = result.Count(s => s?.Contains(content, StringComparison.Ordinal) == true);\n\n            Assert.Equal(1, countOfOccurrences);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/ExitCommandTests.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.txt file in the project root for more information.\n\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class ExitCommandTests : CommandTestsBase\n    {\n        [Fact]\n        public async Task ExecuteAsync_Always_IsExitingIsTrue()\n        {\n            ArrangeInputs(\"exit\", out MockedShellState shellState, out HttpState httpState, out ICoreParseResult parseResult);\n\n            ExitCommand exitCommand = new ExitCommand();\n\n            await exitCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.True(shellState.IsExiting);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_Always_DoesNotWritePrompt()\n        {\n            ArrangeInputs(\"exit\", out MockedShellState shellState, out HttpState httpState, out ICoreParseResult parseResult);\n\n            ExitCommand exitCommand = new ExitCommand();\n\n            await exitCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Empty(shellState.Output);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/GetCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class GetCommandTests : CommandTestsBase\n    {\n        private string _baseAddress;\n        private string _path;\n        private IDictionary<string, string> _urlsWithResponse = new Dictionary<string, string>();\n\n        public GetCommandTests()\n        {\n            _baseAddress = \"http://localhost:5050/\";\n            _path = \"this/is/a/test/route\";\n\n            _urlsWithResponse.Add(_baseAddress, \"This is a response from the root.\");\n            _urlsWithResponse.Add(_baseAddress + _path, \"This is a test response.\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoBasePath_VerifyError()\n        {\n            ArrangeInputs(commandText: \"GET\",\n                baseAddress: null,\n                path: null,\n                urlsWithResponse: null,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            string expectedErrorMessage = Strings.Error_NoBasePath.SetColor(httpState.ErrorColor);\n\n            GetCommand getCommand = new GetCommand(fileSystem, preferences, new NullTelemetry());\n            await getCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(expectedErrorMessage, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithMultipartRoute_VerifyOutput()\n        {\n            ArrangeInputs(commandText: \"GET\",\n                baseAddress: _baseAddress,\n                path: _path,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            GetCommand getCommand = new GetCommand(fileSystem, preferences, new NullTelemetry());\n            await getCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response.\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Equal(\"HTTP/1.1 200 OK\", result[0]);\n            Assert.Equal(expectedResponse, result[1]);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithOnlyBaseAddress_VerifyOutput()\n        {\n            ArrangeInputs(commandText: \"GET\",\n                baseAddress: _baseAddress,\n                path: null,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            GetCommand getCommand = new GetCommand(fileSystem, preferences, new NullTelemetry());\n            await getCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a response from the root.\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Equal(\"HTTP/1.1 200 OK\", result[0]);\n            Assert.Equal(expectedResponse, result[1]);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithJsonContentTypeInHeader_FormatsResponseContent()\n        {\n            string json = @\"{\n\"\"swagger\"\": \"\"2.0\"\",\n\"\"info\"\": {\n\"\"version\"\": \"\"v1\"\"\n},\n\"\"paths\"\": {\n\"\"/api/Employees\"\": {\n}\n}\n}\";\n            string path  = \"this/is/a/test/route/for/formatting\";\n\n            _urlsWithResponse.Add(_baseAddress + path, json);\n\n            ArrangeInputs(commandText: \"GET\",\n                baseAddress: _baseAddress,\n                path: path,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                contentType: \"application/json\");\n\n            GetCommand getCommand = new GetCommand(fileSystem, preferences, new NullTelemetry());\n            await getCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            int expectedHeaderLength = 2;\n            string expectedResponse = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/api/Employees\"\": {\n    }\n  }\n}\";\n\n            string[] expectedResponseLines = expectedResponse.Split(Environment.NewLine);\n\n            List<string> result = shellState.Output;\n\n            Assert.Equal(expectedHeaderLength + expectedResponseLines.Length, result.Count);\n            Assert.Equal(\"HTTP/1.1 200 OK\", result[0]);\n            Assert.Equal(\"Content-Type: application/json\", result[1]);\n            for (int expectedIndex = 0; expectedIndex < expectedResponseLines.Length; expectedIndex++)\n            {\n                Assert.Equal(expectedResponseLines[expectedIndex], result[expectedIndex + expectedHeaderLength], StringComparer.Ordinal);\n            }\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithTextContentTypeInHeader_DoesNotFormatResponseContent()\n        {\n            string unformattedResponse = \"This is an        unformatted response.      \";\n\n            string path = \"this/is/a/test/route/for/formatting\";\n\n            _urlsWithResponse.Add(_baseAddress + path, unformattedResponse);\n\n            ArrangeInputs(commandText: \"GET\",\n                baseAddress: _baseAddress,\n                path: path,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                contentType: \"text/plain\");\n\n            GetCommand getCommand = new GetCommand(fileSystem, preferences, new NullTelemetry());\n            await getCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            List<string> result = shellState.Output;\n\n            Assert.Equal(3, result.Count);\n            Assert.Equal(\"HTTP/1.1 200 OK\", result[0]);\n            Assert.Equal(\"Content-Type: text/plain\", result[1]);\n            Assert.Equal(unformattedResponse, result[2]);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithHeaderOptionAndEchoOn_VerifyOutputContainsRequestAndReaponseHeaders()\n        {\n            string unformattedResponse = \"This is a test response.\";\n\n            string path = \"this/is/a/test/route/for/formatting\";\n\n            _urlsWithResponse.Add(_baseAddress + path, unformattedResponse);\n\n            ArrangeInputs(commandText: \"GET --header Accept=text/plain\",\n                baseAddress: _baseAddress,\n                path: path,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                contentType: \"text/plain\");\n\n            httpState.EchoRequest = true;\n\n            GetCommand getCommand = new GetCommand(fileSystem, preferences, new NullTelemetry());\n            await getCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            List<string> result = shellState.Output;\n\n            Assert.Equal(8, result.Count);\n            Assert.Equal(\"Request to http://localhost:5050...\", result[0]);\n            Assert.Equal(\"GET /this/is/a/test/route/for/formatting HTTP/1.1\", result[1]);\n            Assert.Equal(\"Accept: text/plain\", result[2]);\n            Assert.Equal(\"User-Agent: HTTP-REPL\", result[3]);\n            Assert.Equal(\"Response from http://localhost:5050...\", result[4]);\n            Assert.Equal(\"HTTP/1.1 200 OK\", result[5]);\n            Assert.Equal(\"Content-Type: text/plain\", result[6]);\n            Assert.Equal(unformattedResponse, result[7]);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithSameHeadersAndBodyPaths_VerifyError()\n        {\n            // Arrange\n            string fileName = \"\\\"/myfile.txt\\\"\";\n\n            ArrangeInputs(commandText: $\"GET --response:headers {fileName} --response:body {fileName}\",\n                baseAddress: _baseAddress,\n                path: null,\n                urlsWithResponse: null,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            string expectedErrorMessage = Strings.BaseHttpCommand_Error_SameBodyAndHeaderFileName.SetColor(httpState.ErrorColor);\n\n            GetCommand getCommand = new GetCommand(fileSystem, preferences, new NullTelemetry());\n\n            // Act\n            await getCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            // Assert\n            Assert.Equal(expectedErrorMessage, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithPathAndOptions_SendsTelemetry()\n        {\n            // Arrange\n            string expectedPath = \"/path\";\n            string expectedMethod = \"GET\";\n            ArrangeInputs(commandText: $\"{expectedMethod} {expectedPath} --no-formatting --header Content-Length=20\",\n                baseAddress: _baseAddress,\n                path: _path,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            TelemetryCollector telemetry = new TelemetryCollector();\n            GetCommand getCommand = new GetCommand(fileSystem, preferences, telemetry);\n\n            // Act\n            await getCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            // Assert\n            Assert.Single(telemetry.Telemetry);\n            TelemetryCollector.CollectedTelemetry collectedTelemetry = telemetry.Telemetry[0];\n            Assert.Equal(TelemetryEventNames.HttpCommand, collectedTelemetry.EventName, ignoreCase: true);\n            Assert.Equal(expectedMethod, collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_Method]);\n            Assert.Equal(\"True\", collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_PathSpecified]);\n            Assert.Equal(\"True\", collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_NoFormattingSpecified]);\n            Assert.Equal(\"True\", collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_HeaderSpecified]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_ResponseHeadersFileSpecified]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_StreamingSpecified]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_NoBodySpecified]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_RequestBodyContentSpecified]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_RequestBodyFileSpecified]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[TelemetryPropertyNames.HttpCommand_ResponseBodyFileSpecified]);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/HeadCommandTests.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class HeadCommandTests : CommandTestsBase\n    {\n        private string _baseAddress;\n        private string _path;\n        private IDictionary<string, string> _urlsWithResponse = new Dictionary<string, string>();\n\n        public HeadCommandTests()\n        {\n            _baseAddress = \"http://localhost:5050/\";\n            _path = \"this/is/a/test/route\";\n\n            _urlsWithResponse.Add(_baseAddress, \"Header value for root HEAD request.\");\n            _urlsWithResponse.Add(_baseAddress + _path, \"Header value for HEAD request with route.\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoBasePath_VerifyError()\n        {\n            ArrangeInputs(commandText: \"HEAD\",\n                baseAddress: null,\n                path: null,\n                urlsWithResponse: null,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            string expectedErrorMessage = Strings.Error_NoBasePath.SetColor(httpState.ErrorColor);\n\n            HeadCommand headCommand = new HeadCommand(fileSystem, preferences, new NullTelemetry());\n            await headCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(expectedErrorMessage, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithMultipartRoute_VerifyHeaders()\n        {\n            ArrangeInputs(commandText: \"HEAD\",\n                baseAddress: _baseAddress,\n                path: _path,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                header: \"X-HTTPREPL-TESTHEADER\");\n\n            HeadCommand headCommand = new HeadCommand(fileSystem, preferences, new NullTelemetry());\n            await headCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedHeader = \"X-HTTPREPL-TESTHEADER: Header value for HEAD request with route.\";\n            List<string> result = shellState.Output;\n\n            Assert.True(result.Count >= 2);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedHeader, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithOnlyBaseAddress_VerifyHeaders()\n        {\n            ArrangeInputs(commandText: \"HEAD\",\n                baseAddress: _baseAddress,\n                path: null,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                header: \"X-HTTPREPL-TESTHEADER\");\n\n            HeadCommand headCommand = new HeadCommand(fileSystem, preferences, new NullTelemetry());\n            await headCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedHeader = \"X-HTTPREPL-TESTHEADER: Header value for root HEAD request.\";\n            List<string> result = shellState.Output;\n\n            Assert.True(result.Count >= 2);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedHeader, result);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/HelpCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class HelpCommandTests : CommandTestsBase\n    {\n        [Theory]\n        [InlineData(\"help\", true)]\n        [InlineData(\"HELP\", true)]\n        [InlineData(\"hElP\", true)]\n        [InlineData(\"hep\", null)]\n        public void CanHandle(string commandText, bool? expected)\n        {\n            HttpState httpState = GetHttpState(out _, out _);\n            ICoreParseResult parseResult = CreateCoreParseResult(commandText);\n            IShellState shellState = new MockedShellState();\n\n            HelpCommand helpCommand = new HelpCommand();\n\n            bool? result = helpCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Theory]\n        [InlineData(\"help c\", \"clear\", \"cls\", \"cd\")]\n        [InlineData(\"help r\", \"run\")]\n        [InlineData(\"help z\")]\n        public void Suggest(string commandText, params string[] expectedResults)\n        {\n            HttpState httpState = GetHttpState(out MockedFileSystem fileSystem, out _);\n            ICoreParseResult parseResult = CreateCoreParseResult(commandText);\n            IConsoleManager consoleManager = new LoggingConsoleManagerDecorator(new NullConsoleManager());\n            DefaultCommandDispatcher<HttpState> commandDispatcher = DefaultCommandDispatcher.Create((ss) => { }, httpState);\n            commandDispatcher.AddCommand(new ClearCommand());\n            commandDispatcher.AddCommand(new ChangeDirectoryCommand());\n            commandDispatcher.AddCommand(new RunCommand(fileSystem));\n            IShellState shellState = new ShellState(commandDispatcher, consoleManager: consoleManager);\n\n            HelpCommand helpCommand = new HelpCommand();\n\n            IEnumerable<string> result = helpCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.NotNull(result);\n\n            List<string> resultList = result.ToList();\n\n            Assert.Equal(expectedResults.Length, resultList.Count);\n\n            for (int index = 0; index < expectedResults.Length; index++)\n            {\n                Assert.Contains(expectedResults[index], resultList, StringComparer.OrdinalIgnoreCase);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/ListCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.OpenApi;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class ListCommandTests : CommandTestsBase\n    {\n        [Fact]\n        public async Task ExecuteAsync_NoBaseAddressOnHttpState_ShowsWarning()\n        {\n            ArrangeInputs(commandText: \"ls\",\n                          baseAddress: \"http://localhost/\",\n                          path: \"/\",\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            httpState.BaseAddress = null;\n            httpState.SwaggerEndpoint = new Uri(\"http://localhost/swagger.json\");\n            ApiDefinition apiDefinition = new ApiDefinition()\n            {\n                DirectoryStructure = new DirectoryStructure(null)\n            };\n            httpState.ApiDefinition = apiDefinition;\n\n            ListCommand listCommand = new ListCommand(preferences);\n\n            await listCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string actualOutput = string.Join(Environment.NewLine, shellState.Output);\n            Assert.Equal(Resources.Strings.ListCommand_Error_NoBaseAddress, actualOutput);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_NoSwagger_ShowsWarning()\n        {\n            ArrangeInputs(commandText: \"ls\",\n                          baseAddress: \"http://localhost/\",\n                          path: \"/\",\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            httpState.SwaggerEndpoint = null;\n            ApiDefinition apiDefinition = new ApiDefinition()\n            {\n                DirectoryStructure = new DirectoryStructure(null)\n            };\n            httpState.ApiDefinition = apiDefinition;\n\n            ListCommand listCommand = new ListCommand(preferences);\n\n            await listCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string actualOutput = string.Join(Environment.NewLine, shellState.Output);\n            Assert.Equal(Resources.Strings.ListCommand_Error_NoDirectoryStructure, actualOutput);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_NoStructure_ShowsWarning()\n        {\n            ArrangeInputs(commandText: \"ls\",\n                          baseAddress: \"http://localhost/\",\n                          path: \"/\",\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            httpState.SwaggerEndpoint = new Uri(\"http://localhost/swagger.json\");\n            httpState.ApiDefinition = null;\n\n            ListCommand listCommand = new ListCommand(preferences);\n\n            await listCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string actualOutput = string.Join(Environment.NewLine, shellState.Output);\n            Assert.Equal(Resources.Strings.ListCommand_Error_NoDirectoryStructure, actualOutput);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithBaseAddressSwaggerAndStructure_NoWarning()\n        {\n            string response = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v2 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/api\"\": {\n      \"\"get\"\": {\n        \"\"tags\"\": [ \"\"Employees\"\" ],\n        \"\"operationId\"\": \"\"GetEmployee\"\",\n        \"\"consumes\"\": [],\n        \"\"produces\"\": [ \"\"text/plain\"\", \"\"application/json\"\", \"\"text/json\"\" ],\n        \"\"parameters\"\": [],\n        \"\"responses\"\": {\n          \"\"200\"\": {\n            \"\"description\"\": \"\"Success\"\",\n            \"\"schema\"\": {\n              \"\"uniqueItems\"\": false,\n              \"\"type\"\": \"\"array\"\"\n            }\n          }\n        }\n      }\n    }\n  }\n}\";\n\n            ArrangeInputs(commandText: \"ls\",\n                          baseAddress: \"http://localhost/\",\n                          path: \"/\",\n                          urlsWithResponse: new Dictionary<string, string>() { { \"http://localhost/swagger.json\", response } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            httpState.SwaggerEndpoint = new Uri(\"http://localhost/swagger.json\");\n\n            ListCommand listCommand = new ListCommand(preferences);\n\n            await listCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string actualOutput = string.Join(Environment.NewLine, shellState.Output);\n            Assert.DoesNotContain(Resources.Strings.ListCommand_Error_NoBaseAddress, actualOutput, StringComparison.Ordinal);\n            Assert.DoesNotContain(Resources.Strings.ListCommand_Error_NoDirectoryStructure, actualOutput, StringComparison.Ordinal);\n        }\n\n        [Fact]\n        public void Suggest_WithBlankSecondParameter_NoExceptionAndCorrectSuggestions()\n        {\n            // Arrange\n            ArrangeInputs(commandText: \"dir \",\n                          baseAddress: \"https://localhost/\",\n                          path: \"/\",\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            ListCommand listCommand = new ListCommand(preferences);\n\n            // Act\n            List<string> suggestions = listCommand.Suggest(shellState, httpState, parseResult).ToList();\n\n            // Assert\n            for (int optionIndex = 0; optionIndex < listCommand.InputSpec.Options.Count; optionIndex++)\n            {\n                CommandOptionSpecification option = listCommand.InputSpec.Options[optionIndex];\n                for (int formIndex = 0; formIndex < option.Forms.Count; formIndex++)\n                {\n                    Assert.Contains(option.Forms[formIndex], suggestions, StringComparer.Ordinal);\n                }\n            }\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithMethods_MethodsAreUppercase()\n        {\n            string response = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v2 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/api\"\": {\n      \"\"get\"\": {\n      },\n      \"\"post\"\": {\n      }\n    }\n  }\n}\";\n\n            ArrangeInputs(commandText: \"ls\",\n                          baseAddress: \"http://localhost/\",\n                          path: \"/api\",\n                          urlsWithResponse: new Dictionary<string, string>() { { \"http://localhost/swagger.json\", response } },\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            httpState.SwaggerEndpoint = new Uri(\"http://localhost/swagger.json\");\n\n            ListCommand listCommand = new ListCommand(preferences);\n\n            await listCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string actualOutput = string.Join(Environment.NewLine, shellState.Output);\n            Assert.Contains(\"[GET|POST]\", actualOutput, StringComparison.Ordinal);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/OptionsCommandTests.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class OptionsCommandTests : CommandTestsBase\n    {\n        private string _baseAddress;\n        private string _path;\n        private IDictionary<string, string> _urlsWithResponse = new Dictionary<string, string>();\n\n        public OptionsCommandTests()\n        {\n            _baseAddress = \"http://localhost:5050/\";\n            _path = \"this/is/a/test/route\";\n\n            _urlsWithResponse.Add(_baseAddress, \"Header value for root OPTIONS request.\");\n            _urlsWithResponse.Add(_baseAddress + _path, \"Header value for OPTIONS request with route.\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoBasePath_VerifyError()\n        {\n            ArrangeInputs(commandText: \"OPTIONS\",\n                baseAddress: null,\n                path: null,\n                urlsWithResponse: null,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            string expectedErrorMessage = Strings.Error_NoBasePath.SetColor(httpState.ErrorColor);\n\n            OptionsCommand optionsCommand = new OptionsCommand(fileSystem, preferences, new NullTelemetry());\n            await optionsCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(expectedErrorMessage, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithMultipartRoute_VerifyOutput()\n        {\n            ArrangeInputs(commandText: \"OPTIONS\",\n                baseAddress: _baseAddress,\n                path: _path,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                header: \"X-HTTPREPL-TESTHEADER\");\n\n            OptionsCommand optionsCommand = new OptionsCommand(fileSystem, preferences, new NullTelemetry());\n            await optionsCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedHeader = \"X-HTTPREPL-TESTHEADER: Header value for OPTIONS request with route.\";\n            List<string> result = shellState.Output;\n\n            Assert.True(result.Count >= 2);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedHeader, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithOnlyBaseAddress_VerifyOutput()\n        {\n            ArrangeInputs(commandText: \"Options\",\n                baseAddress: _baseAddress,\n                path: null,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                header: \"X-HTTPREPL-TESTHEADER\");\n\n            OptionsCommand optionsCommand = new OptionsCommand(fileSystem, preferences, new NullTelemetry());\n            await optionsCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedHeader = \"X-HTTPREPL-TESTHEADER: Header value for root OPTIONS request.\";\n            List<string> result = shellState.Output;\n\n            Assert.True(result.Count >= 2);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedHeader, result);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/PatchCommandTests.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class PatchCommandTests : CommandTestsBase\n    {\n        private string _baseAddress;\n        private string _testPath;\n        private string _noBodyRequiredPath;\n        private IDictionary<string, string> _urlsWithResponse = new Dictionary<string, string>();\n\n        public PatchCommandTests()\n        {\n            _baseAddress = \"http://localhost:5050/\";\n            _testPath = \"this/is/a/test/route\";\n            _noBodyRequiredPath = \"no/body/required\";\n\n            _urlsWithResponse.Add(_baseAddress, \"This is a test response from a PATCH: \\\"Test Patch Body\\\"\");\n            _urlsWithResponse.Add(_baseAddress + _testPath, \"This is a test response from a PATCH: \\\"Test Patch Body\\\"\");\n            _urlsWithResponse.Add(_baseAddress + _noBodyRequiredPath, \"This is a test response from a PATCH: \\\"\\\"\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoBasePath_VerifyError()\n        {\n            ArrangeInputs(commandText: \"PATCH\",\n                baseAddress: null,\n                path: null,\n                urlsWithResponse: null,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            string expectedErrorMessage = Strings.Error_NoBasePath.SetColor(httpState.ErrorColor);\n\n            PatchCommand patchCommand = new PatchCommand(fileSystem, preferences, new NullTelemetry());\n            await patchCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(expectedErrorMessage, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_OnlyBaseAddressWithInlineContent_VerifyResponse()\n        {\n            ArrangeInputs(commandText: \"PATCH --content \\\"Test Patch Body\\\"\",\n                baseAddress: _baseAddress,\n                path: null,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            PatchCommand patchCommand = new PatchCommand(fileSystem, preferences, new NullTelemetry());\n            await patchCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response from a PATCH: \\\"Test Patch Body\\\"\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MultiPartRouteWithInlineContent_VerifyResponse()\n        {\n            ArrangeInputs(commandText: \"PATCH --content \\\"Test Patch Body\\\"\",\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            PatchCommand patchCommand = new PatchCommand(fileSystem, preferences, new NullTelemetry());\n            await patchCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response from a PATCH: \\\"Test Patch Body\\\"\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MultiPartRouteWithNoBodyRequired_VerifyResponse()\n        {\n            ArrangeInputs(commandText: \"PATCH --no-body\",\n                baseAddress: _baseAddress,\n                path: _noBodyRequiredPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            PatchCommand patchCommand = new PatchCommand(fileSystem, preferences, new NullTelemetry());\n            await patchCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response from a PATCH: \\\"\\\"\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MultiPartRouteWithBodyFromFile_VerifyResponse()\n        {\n            string filePath = \"someFilePath.txt\";\n            string fileContents = \"This is a test response from a PATCH: \\\"Test Patch Body From File\\\"\";\n\n            ArrangeInputs(commandText: $\"PATCH --file \" + filePath,\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                readBodyFromFile: true,\n                fileContents: fileContents);\n\n            fileSystem.AddFile(filePath, \"Test Patch Body From File\");\n\n            PatchCommand patchCommand = new PatchCommand(fileSystem, preferences, new NullTelemetry());\n            await patchCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(fileContents, result);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/PostCommandTests.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.HttpRepl.UserProfile;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class PostCommandTests : CommandTestsBase\n    {\n        private string _baseAddress;\n        private string _testPath;\n        private string _noBodyRequiredPath;\n        private IDictionary<string, string> _urlsWithResponse = new Dictionary<string, string>();\n\n        public PostCommandTests()\n        {\n            _baseAddress = \"http://localhost:5050/\";\n            _testPath = \"this/is/a/test/route\";\n            _noBodyRequiredPath = \"no/body/required\";\n\n            _urlsWithResponse.Add(_baseAddress, \"This is a test response from a POST: \\\"Test Post Body\\\"\");\n            _urlsWithResponse.Add(_baseAddress + _testPath, \"This is a test response from a POST: \\\"Test Post Body\\\"\");\n            _urlsWithResponse.Add(_baseAddress + _noBodyRequiredPath, \"This is a test response from a POST: \\\"\\\"\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoBasePath_VerifyError()\n        {\n            ArrangeInputs(commandText: \"POST\",\n                baseAddress: null,\n                path: null,\n                urlsWithResponse: null,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            string expectedErrorMessage = Strings.Error_NoBasePath.SetColor(httpState.ErrorColor);\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(expectedErrorMessage, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_OnlyBaseAddressWithInlineContent_VerifyResponse()\n        {\n            ArrangeInputs(commandText: \"POST --content \\\"Test Post Body\\\"\",\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response from a POST: \\\"Test Post Body\\\"\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithContentTypeHeader_NotDuplicated()\n        {\n            string expectedHeader = \"Content-Type: application/test\";\n            ArrangeInputs(commandText: \"POST --header content-type:application/test --content \\\"Test Post Body\\\"\",\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            httpState.EchoRequest = true;\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            List<string> result = shellState.Output;\n\n            Assert.Equal(8, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Single(result, s => string.Equals(s, expectedHeader, System.StringComparison.Ordinal));\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithOtherContentHeader_NotDuplicated()\n        {\n            string expectedHeader = \"Content-Disposition: inline\";\n            ArrangeInputs(commandText: \"POST --header content-disposition:inline --content \\\"Test Post Body\\\"\",\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            httpState.EchoRequest = true;\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            List<string> result = shellState.Output;\n\n            Assert.Equal(9, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Single(result, s => string.Equals(s, expectedHeader, System.StringComparison.Ordinal));\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNonContentHeader_NotDuplicated()\n        {\n            string expectedHeader = \"TE: compress\";\n            ArrangeInputs(commandText: \"POST --header te:compress --content \\\"Test Post Body\\\"\",\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            httpState.EchoRequest = true;\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n\n            List<string> result = shellState.Output;\n\n            Assert.Equal(9, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Single(result, s => string.Equals(s, expectedHeader, System.StringComparison.Ordinal));\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MultiPartRouteWithInlineContent_VerifyResponse()\n        {\n            ArrangeInputs(commandText: \"POST --content \\\"Test Post Body\\\"\",\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response from a POST: \\\"Test Post Body\\\"\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MultiPartRouteWithNoBodyRequired_VerifyResponse()\n        {\n            ArrangeInputs(commandText: \"POST --no-body\",\n                baseAddress: _baseAddress,\n                path: _noBodyRequiredPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response from a POST: \\\"\\\"\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MultiPartRouteWithBodyFromFile_VerifyResponse()\n        {\n            string filePath = \"someFilePath.txt\";\n            string fileContents = \"This is a test response from a POST: \\\"Test Post Body From File\\\"\";\n\n            ArrangeInputs(commandText: $\"POST --file \" + filePath,\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                readBodyFromFile: true,\n                fileContents: fileContents);\n\n            fileSystem.AddFile(filePath, \"Test Post Body From File\");\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(fileContents, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_NonExistentContentFile_VerifyResponse()\n        {\n            string filePath = \"someFilePath.txt\";\n            string fileContents = \"This is a test response from a POST: \\\"Test Post Body From File\\\"\";\n\n            ArrangeInputs(commandText: $\"POST --file \" + filePath,\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                readBodyFromFile: true,\n                fileContents: fileContents);\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Empty(shellState.Output);\n            Assert.Contains(string.Format(Strings.BaseHttpCommand_Error_ContentFileDoesNotExist, filePath), shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithEditorNotConfigured_VerifyResponse()\n        {\n            ArrangeInputs(commandText: $\"POST\",\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            preferences.SetValue(WellKnownPreference.DefaultEditorCommand, \"\");\n\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Empty(shellState.Output);\n            Assert.Contains(string.Format(Strings.BaseHttpCommand_Error_DefaultEditorNotConfigured, WellKnownPreference.DefaultEditorCommand), shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithEditorDoesNotExist_VerifyResponse()\n        {\n            // Arrange\n            string editorPath = \"FileThatDoesNotExist.exe\";\n            string commandText = \"POST https://localhost/\";\n\n            MockedShellState shellState = new MockedShellState();\n            IFileSystem fileSystem = new MockedFileSystem();\n            IUserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            IPreferences preferences = new UserFolderPreferences(fileSystem, userProfileDirectoryProvider, null);\n            ICoreParseResult parseResult = CoreParseResultHelper.Create(commandText);\n            HttpClient httpClient = new HttpClient();\n            HttpState httpState = new HttpState(preferences, httpClient);\n            PostCommand postCommand = new PostCommand(fileSystem, preferences, new NullTelemetry());\n\n            preferences.SetValue(WellKnownPreference.DefaultEditorCommand, editorPath);\n\n            // Act\n            await postCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            // Execute\n            Assert.Empty(shellState.Output);\n            Assert.Contains(string.Format(Strings.BaseHttpCommand_Error_DefaultEditorDoesNotExist, editorPath), shellState.ErrorMessage);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/PrefCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Runtime.InteropServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.HttpRepl.Tests.Preferences;\nusing Microsoft.HttpRepl.UserProfile;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class PrefCommandTests\n    {\n        [Fact]\n        public async Task ExecuteAsync_UppercaseGetCommand_CorrectOutput()\n        {\n            await ValidateOutput(commandText: $\"pref GET {WellKnownPreference.ProtocolColor}\",\n                                 expectedOutputLines: 1,\n                                 expectedOutputOnLastLineCallback: (preferences) => $\"Configured value: {preferences.CurrentPreferences[WellKnownPreference.ProtocolColor]}\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_LowercaseGetCommand_CorrectOutput()\n        {\n            await ValidateOutput(commandText: $\"pref get {WellKnownPreference.ProtocolColor}\",\n                                 expectedOutputLines: 1,\n                                 expectedOutputOnLastLineCallback: (preferences) => $\"Configured value: {preferences.CurrentPreferences[WellKnownPreference.ProtocolColor]}\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MixedCaseGetCommand_CorrectOutput()\n        {\n            await ValidateOutput(commandText: $\"pref gEt {WellKnownPreference.ProtocolColor}\",\n                                 expectedOutputLines: 1,\n                                 expectedOutputOnLastLineCallback: (preferences) => $\"Configured value: {preferences.CurrentPreferences[WellKnownPreference.ProtocolColor]}\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_UppercaseSetCommand_PreferenceSet()\n        {\n            string expectedValue = \"BoldMagenta\";\n            await ValidatePreference(commandText: $\"pref SET {WellKnownPreference.ProtocolColor} {expectedValue}\",\n                                     preferenceName: WellKnownPreference.ProtocolColor,\n                                     expectedValueCallback: (httpState) => expectedValue);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_LowercaseSetCommand_PreferenceSet()\n        {\n            string expectedValue = \"BoldMagenta\";\n            await ValidatePreference(commandText: $\"pref set {WellKnownPreference.ProtocolColor} {expectedValue}\",\n                                     preferenceName: WellKnownPreference.ProtocolColor,\n                                     expectedValueCallback: (httpState) => expectedValue);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MixedCaseSetCommand_PreferenceSet()\n        {\n            string expectedValue = \"BoldMagenta\";\n            await ValidatePreference(commandText: $\"pref sEt {WellKnownPreference.ProtocolColor} {expectedValue}\",\n                                     preferenceName: WellKnownPreference.ProtocolColor,\n                                     expectedValueCallback: (httpState) => expectedValue);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_SetCommandNoValue_SetToDefault()\n        {\n            IFileSystem fileSystem = new MockedFileSystem();\n            IUserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            UserFolderPreferences preferences = new UserFolderPreferences(fileSystem, userProfileDirectoryProvider, TestDefaultPreferences.GetDefaultPreferences());\n            HttpClient httpClient = new HttpClient();\n            HttpState httpState = new HttpState(preferences, httpClient);\n            MockedShellState shellState = new MockedShellState();\n            PrefCommand command = new PrefCommand(preferences, new NullTelemetry());\n\n            // First, set it to something other than the default and make sure that works.\n            string firstCommandExpectedValue = \"BoldMagenta\";\n            string firstCommandText = $\"pref set {WellKnownPreference.ProtocolColor} {firstCommandExpectedValue}\";\n            ICoreParseResult firstParseResult = CoreParseResultHelper.Create(firstCommandText);\n\n            await command.ExecuteAsync(shellState, httpState, firstParseResult, CancellationToken.None);\n\n            Assert.Empty(shellState.Output);\n            Assert.Equal(firstCommandExpectedValue, preferences.CurrentPreferences[WellKnownPreference.ProtocolColor]);\n\n            // Then, set it to nothing and make sure it goes back to the default\n            string secondCommandText = $\"pref set {WellKnownPreference.ProtocolColor}\";\n            ICoreParseResult secondParseResult = CoreParseResultHelper.Create(secondCommandText);\n\n            await command.ExecuteAsync(shellState, httpState, secondParseResult, CancellationToken.None);\n\n            Assert.Empty(shellState.Output);\n            Assert.Equal(preferences.DefaultPreferences[WellKnownPreference.ProtocolColor], preferences.CurrentPreferences[WellKnownPreference.ProtocolColor]);\n\n        }\n\n        [Fact]\n        public void CanHandle_NoArguments_ReturnsNull()\n        {\n            string commandText = \"\";\n\n            Arrange(commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out _);\n\n            bool? canHandle = command.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(canHandle);\n        }\n\n        [Fact]\n        public void CanHandle_InvalidFirstArgument_ReturnsNull()\n        {\n            string commandText = \"preferences set colors.protocol\";\n\n            Arrange(commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out _);\n\n            bool? canHandle = command.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(canHandle);\n        }\n\n        [Fact]\n        public void CanHandle_SetWithNoName_DisplaysError()\n        {\n            string commandText = \"pref set\";\n\n            Arrange(commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out _);\n\n            bool? canHandle = command.CanHandle(shellState, httpState, parseResult);\n\n            Assert.False(canHandle);\n            Assert.Equal(Resources.Strings.PrefCommand_Error_NoPreferenceName, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public void CanHandle_SetWithBlankName_DisplaysError()\n        {\n            string commandText = \"pref set  \";\n\n            Arrange(commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out _);\n\n            bool? canHandle = command.CanHandle(shellState, httpState, parseResult);\n\n            Assert.False(canHandle);\n            Assert.Equal(Resources.Strings.PrefCommand_Error_NoPreferenceName, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public void GetHelpDetails_NoSubCommands_DisplaysCommandSyntax()\n        {\n            string commandText = \"pref\";\n\n            Arrange(commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out _);\n\n            string output = command.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Contains(\"pref [get/set] {setting} [{value}]\", output);\n        }\n\n        [Fact]\n        public void GetHelpDetails_Get_DisplaysCommandSyntax()\n        {\n            string commandText = \"pref get\";\n\n            Arrange(commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out _);\n\n            string output = command.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Contains(\"pref get [{setting}]\", output);\n        }\n\n        [Fact]\n        public void GetHelpDetails_Set_DisplaysCommandSyntax()\n        {\n            string commandText = \"pref set\";\n\n            Arrange(commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out _);\n\n            string output = command.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Contains(\"pref set {setting} [{value}]\", output);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithGet_SendsTelemetry()\n        {\n            Arrange($\"pref get {WellKnownPreference.DefaultEditorCommand}\",\n                    out HttpState httpState,\n                    out MockedShellState shellState,\n                    out ICoreParseResult parseResult,\n                    out UserFolderPreferences preferences);\n\n            TelemetryCollector telemetry = new TelemetryCollector();\n\n            PrefCommand command = new PrefCommand(preferences, telemetry);\n\n            await command.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(telemetry.Telemetry);\n            TelemetryCollector.CollectedTelemetry collectedTelemetry = telemetry.Telemetry[0];\n            Assert.Equal(\"Preference\", collectedTelemetry.EventName);\n            Assert.Equal(\"Get\", collectedTelemetry.Properties[\"GetOrSet\"]);\n            Assert.Equal(WellKnownPreference.DefaultEditorCommand, collectedTelemetry.Properties[\"PreferenceName\"]);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithSet_SendsTelemetry()\n        {\n            Arrange($\"pref set {WellKnownPreference.DefaultEditorCommand} value\",\n                    out HttpState httpState,\n                    out MockedShellState shellState,\n                    out ICoreParseResult parseResult,\n                    out UserFolderPreferences preferences);\n\n            TelemetryCollector telemetry = new TelemetryCollector();\n\n            PrefCommand command = new PrefCommand(preferences, telemetry);\n\n            await command.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(telemetry.Telemetry);\n            TelemetryCollector.CollectedTelemetry collectedTelemetry = telemetry.Telemetry[0];\n            Assert.Equal(\"Preference\", collectedTelemetry.EventName);\n            Assert.Equal(\"Set\", collectedTelemetry.Properties[\"GetOrSet\"]);\n            Assert.Equal(WellKnownPreference.DefaultEditorCommand, collectedTelemetry.Properties[\"PreferenceName\"]);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithGetAndUnknownName_SendsTelemetryWithHashedName()\n        {\n            Arrange(\"pref set preferenceName value\",\n                    out HttpState httpState,\n                    out MockedShellState shellState,\n                    out ICoreParseResult parseResult,\n                    out UserFolderPreferences preferences);\n\n            TelemetryCollector telemetry = new TelemetryCollector();\n\n            PrefCommand command = new PrefCommand(preferences, telemetry);\n\n            await command.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(telemetry.Telemetry);\n            TelemetryCollector.CollectedTelemetry collectedTelemetry = telemetry.Telemetry[0];\n            Assert.Equal(\"Preference\", collectedTelemetry.EventName);\n            Assert.Equal(\"Set\", collectedTelemetry.Properties[\"GetOrSet\"]);\n            Assert.Equal(Sha256Hasher.Hash(\"preferenceName\"), collectedTelemetry.Properties[\"PreferenceName\"]);\n        }\n\n        [Theory]\n        [MemberData(nameof(ExecuteAsync_SetDefaultEditorToVSCode_ShowsWarning_Data))]\n        public async Task ExecuteAsync_SetDefaultEditorToVSCode_ShowsWarning(string commandText, OSPlatform intendedPlatform)\n        {\n            // Arrange\n            Arrange($\"pref set {WellKnownPreference.DefaultEditorCommand} \\\"{commandText}\\\"\",\n                    out HttpState httpState,\n                    out MockedShellState shellState,\n                    out ICoreParseResult parseResult,\n                    out UserFolderPreferences preferences);\n\n            PrefCommand command = new PrefCommand(preferences, new NullTelemetry());\n\n            string expectedWarning = string.Format(Resources.Strings.PrefCommand_Set_VSCode, WellKnownPreference.DefaultEditorArguments).SetColor(httpState.WarningColor);\n\n            // Act\n            await command.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            // Assert\n            if (RuntimeInformation.IsOSPlatform(intendedPlatform))\n            {\n                Assert.Contains(expectedWarning, shellState.Output, StringComparer.CurrentCulture);\n            }\n            else\n            {\n                Assert.DoesNotContain(expectedWarning, shellState.Output, StringComparer.CurrentCulture);\n            }\n        }\n\n        public static IEnumerable<object[]> ExecuteAsync_SetDefaultEditorToVSCode_ShowsWarning_Data { get; } = new List<object[]>()\n        {\n            new object[] { \"c:\\\\users\\\\username\\\\appdata\\\\local\\\\programs\\\\Microsoft VS Code\\\\Code.exe\", OSPlatform.Windows },\n            new object[] { \"c:\\\\users\\\\username\\\\appdata\\\\local\\\\programs\\\\Microsoft VS Code Insiders\\\\Code - Insiders.exe\", OSPlatform.Windows },\n            new object[] { \"C:\\\\Program Files\\\\Microsoft VS Code\\\\Code.exe\", OSPlatform.Windows },\n            new object[] { \"/usr/bin/code\", OSPlatform.Linux },\n            new object[] { \"/usr/bin/code-insiders\", OSPlatform.Linux },\n            new object[] { \"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code\", OSPlatform.OSX },\n            new object[] { \"/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code-insiders\", OSPlatform.OSX },\n        };\n\n        private static async Task ValidatePreference(string commandText, string preferenceName, Func<HttpState, string> expectedValueCallback)\n        {\n            Arrange(commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out UserFolderPreferences preferences);\n\n            await command.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Empty(shellState.Output);\n            Assert.Equal(expectedValueCallback(httpState), preferences.CurrentPreferences[preferenceName]);\n        }\n\n        private static async Task ValidateOutput(string commandText, int expectedOutputLines, Func<UserFolderPreferences, string> expectedOutputOnLastLineCallback)\n        {\n            Arrange(commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out UserFolderPreferences preferences);\n\n            await command.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(shellState.Output);\n            Assert.Equal(expectedOutputOnLastLineCallback(preferences), shellState.Output[0]);\n        }\n\n        private static void Arrange(string commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out PrefCommand command, out UserFolderPreferences preferences)\n        {\n            IFileSystem fileSystem = new MockedFileSystem();\n            IUserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            preferences = new UserFolderPreferences(fileSystem, userProfileDirectoryProvider, TestDefaultPreferences.GetDefaultPreferences());\n            HttpClient httpClient = new HttpClient();\n            httpState = new HttpState(preferences, httpClient);\n            shellState = new MockedShellState();\n            parseResult = CoreParseResultHelper.Create(commandText);\n            command = new PrefCommand(preferences, new NullTelemetry());\n        }\n\n        private static void Arrange(string commandText, out HttpState httpState, out MockedShellState shellState, out ICoreParseResult parseResult, out UserFolderPreferences preferences)\n        {\n            Arrange(commandText, out httpState, out shellState, out parseResult, out _, out preferences);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/PutCommandTests.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class PutCommandTests : CommandTestsBase\n    {\n        private string _baseAddress;\n        private string _testPath;\n        private string _noBodyRequiredPath;\n        private IDictionary<string, string> _urlsWithResponse = new Dictionary<string, string>();\n\n        public PutCommandTests()\n        {\n            _baseAddress = \"http://localhost:5050/\";\n            _testPath = \"this/is/a/test/route\";\n            _noBodyRequiredPath = \"no/body/required\";\n\n            _urlsWithResponse.Add(_baseAddress, \"This is a test response from a PUT: \\\"Test Put Body\\\"\");\n            _urlsWithResponse.Add(_baseAddress + _testPath, \"This is a test response from a PUT: \\\"Test Put Body\\\"\");\n            _urlsWithResponse.Add(_baseAddress + _noBodyRequiredPath, \"This is a test response from a PUT: \\\"\\\"\");\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoBasePath_VerifyError()\n        {\n            ArrangeInputs(commandText: \"PUT\",\n                baseAddress: null,\n                path: null,\n                urlsWithResponse: null,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            string expectedErrorMessage = Strings.Error_NoBasePath.SetColor(httpState.ErrorColor);\n\n            PutCommand putCommand = new PutCommand(fileSystem, preferences, new NullTelemetry());\n            await putCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(expectedErrorMessage, shellState.ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_OnlyBaseAddressWithInlineContent_VerifyResponse()\n        {\n            ArrangeInputs(commandText: \"PUT --content \\\"Test Put Body\\\"\",\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            PutCommand putCommand = new PutCommand(fileSystem, preferences, new NullTelemetry());\n            await putCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response from a PUT: \\\"Test Put Body\\\"\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MultiPartRouteWithInlineContent_VerifyResponse()\n        {\n            ArrangeInputs(commandText: \"PUT --content \\\"Test Put Body\\\"\",\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            PutCommand putCommand = new PutCommand(fileSystem, preferences, new NullTelemetry());\n            await putCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response from a PUT: \\\"Test Put Body\\\"\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MultiPartRouteWithNoBodyRequired_VerifyResponse()\n        {\n            ArrangeInputs(commandText: \"PUT --no-body\",\n                baseAddress: _baseAddress,\n                path: _noBodyRequiredPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences);\n\n            PutCommand putCommand = new PutCommand(fileSystem, preferences, new NullTelemetry());\n            await putCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string expectedResponse = \"This is a test response from a PUT: \\\"\\\"\";\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(expectedResponse, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_MultiPartRouteWithBodyFromFile_VerifyResponse()\n        {\n            string filePath = \"someFilePath.txt\";\n            string fileContents = \"This is a test response from a PUT: \\\"Test Put Body From File\\\"\";\n\n            ArrangeInputs(commandText: $\"PUT --file \" + filePath,\n                baseAddress: _baseAddress,\n                path: _testPath,\n                urlsWithResponse: _urlsWithResponse,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                out MockedFileSystem fileSystem,\n                out IPreferences preferences,\n                readBodyFromFile: true,\n                fileContents: fileContents);\n\n            fileSystem.AddFile(filePath, \"Test Put Body From File\");\n\n            PutCommand putCommand = new PutCommand(fileSystem, preferences, new NullTelemetry());\n            await putCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            List<string> result = shellState.Output;\n\n            Assert.Equal(2, result.Count);\n            Assert.Contains(\"HTTP/1.1 200 OK\", result);\n            Assert.Contains(fileContents, result);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/RunCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.Repl;\nusing Microsoft.Repl.Commanding;\nusing Microsoft.Repl.ConsoleHandling;\nusing Microsoft.Repl.Parsing;\nusing Moq;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class RunCommandTests : CommandTestsBase, IDisposable\n    {\n        private string _pathToScript = Path.Combine(Directory.GetCurrentDirectory(), \"InputFileForRunCommand.txt\");\n\n        [Fact]\n        public void CanHandle_WithNoParseResultSections_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: string.Empty,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            bool? result = runCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithFirstParseResultSectionNotEqualToName_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"test name.txt\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            bool? result = runCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithValidInput_ReturnsTrue()\n        {\n            ArrangeInputs(parseResultSections: \"run InputFileForRunCommand.txt\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            bool? result = runCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.True(result);\n        }\n\n        [Fact]\n        public void GetHelpSummary_ReturnsDescription()\n        {\n            ArrangeInputs(parseResultSections: string.Empty,\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult _);\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            string result = runCommand.GetHelpSummary(shellState, httpState);\n\n            Assert.Equal(Strings.RunCommand_HelpSummary, result);\n        }\n\n        [Fact]\n        public void GetHelpDetails_WithEmptyParseResultSection_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: string.Empty,\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            string result = runCommand.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void GetHelpDetails_WithFirstParseResultSectionNotEqualToName_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"section1 section2 section3\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            string result = runCommand.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void GetHelpDetails_WithValidInput_HelpDetails()\n        {\n            ArrangeInputs(parseResultSections: \"run InputFileForRunCommand.txt\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            string expected = \"\\u001b[1mUsage: \\u001b[39mrun {path to script}\" + Environment.NewLine + Environment.NewLine +\n                \"Runs the specified script.\" + Environment.NewLine +\n                \"A script is a text file containing one CLI command per line. Each line will be run as if it was typed into the CLI.\" + Environment.NewLine + Environment.NewLine +\n                \"When +history option is specified, commands specified in the text file will be added to command history.\" + Environment.NewLine;\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            string result = runCommand.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_IfFileDoesNotExist_WritesToConsoleManagerError()\n        {\n            ArrangeInputs(parseResultSections: \"run InputFileForRunCommand.txt\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            await runCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            VerifyErrorMessageWasWrittenToConsoleManagerError(shellState);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithValidInput_ExecutesTheCommandsInTheScript()\n        {\n            string commands = @\"set header name value1 value2\";\n\n            if (!File.Exists(_pathToScript))\n            {\n                File.WriteAllText(_pathToScript, commands);\n            }\n\n            string parseResultSections = \"run \" + _pathToScript;\n            ArrangeInputs(parseResultSections: parseResultSections,\n                 out MockedShellState _,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            IShellState shellState = GetShellState(commands, httpState);\n            MockedFileSystem mockedFileSystem = new MockedFileSystem();\n            mockedFileSystem.AddFile(_pathToScript, commands);\n            RunCommand runCommand = new RunCommand(mockedFileSystem);\n\n            await runCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Dictionary<string, IEnumerable<string>> headers = httpState.Headers;\n            KeyValuePair<string, IEnumerable<string>> firstHeader = headers.First();\n            KeyValuePair<string, IEnumerable<string>> secondHeader = headers.ElementAt(1);\n\n            Assert.Equal(2, httpState.Headers.Count);\n            Assert.Equal(\"User-Agent\", firstHeader.Key);\n            Assert.Equal(\"HTTP-REPL\", firstHeader.Value.First());\n\n            Assert.Equal(\"name\", secondHeader.Key);\n            Assert.Equal(\"value1\", secondHeader.Value.First());\n            Assert.Equal(\"value2\", secondHeader.Value.ElementAt(1));\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithHistoryOption_AddsCommandsExecutedFromScriptToCommandHistory()\n        {\n            string commands = @\"set header name value1 value2\";\n\n            if (!File.Exists(_pathToScript))\n            {\n                File.WriteAllText(_pathToScript, commands);\n            }\n\n            string parseResultSections = \"run \" + _pathToScript + \" +history\";\n            ArrangeInputs(parseResultSections: parseResultSections,\n                 out MockedShellState _,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            IShellState shellState = GetShellState(commands, httpState);\n            MockedFileSystem mockedFileSystem = new MockedFileSystem();\n            mockedFileSystem.AddFile(_pathToScript, commands);\n            RunCommand runCommand = new RunCommand(mockedFileSystem);\n\n            await runCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string previousCommand = shellState.CommandHistory.GetPreviousCommand();\n\n            Assert.Equal(commands, previousCommand);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithoutHistoryOption_AvoidsAddingCommandsExecutedFromScriptToCommandHistory()\n        {\n            string commands = @\"set header name value1 value2\";\n\n            if (!File.Exists(_pathToScript))\n            {\n                File.WriteAllText(_pathToScript, commands);\n            }\n\n            string parseResultSections = \"run \" + _pathToScript;\n            ArrangeInputs(parseResultSections: parseResultSections,\n                 out MockedShellState _,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            IShellState shellState = GetShellState(commands, httpState);\n            MockedFileSystem mockedFileSystem = new MockedFileSystem();\n            mockedFileSystem.AddFile(_pathToScript, commands);\n            RunCommand runCommand = new RunCommand(mockedFileSystem);\n\n            await runCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            string previousCommand = shellState.CommandHistory.GetPreviousCommand();\n\n            Assert.True(string.IsNullOrEmpty(previousCommand));\n        }\n\n        [Fact]\n        public void Suggest_WithSelectedSectionAtZeroAndEmptyParseResultSection_ReturnsName()\n        {\n            ArrangeInputs(parseResultSections: string.Empty,\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                caretPosition: 0);\n\n            string expected = \"run\";\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            IEnumerable<string> result = runCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.Single(result);\n            Assert.Equal(expected, result.First());\n        }\n\n        [Fact]\n        public void Suggest_WithSelectedSectionAtZeroAndParseResultSectionStartsWithName_ReturnsName()\n        {\n            ArrangeInputs(parseResultSections: \"r\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult,\n                caretPosition: 0);\n\n            string expected = \"run\";\n\n            RunCommand runCommand = new RunCommand(new MockedFileSystem());\n            IEnumerable<string> result = runCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.Single(result);\n            Assert.Equal(expected, result.First());\n        }\n\n        [Fact]\n        public void Suggest_WithSelectedSectionAtOneAndValidParseResultSection_ReturnsCompletionEntries()\n        {\n            string pathToScript = Path.Combine(Directory.GetCurrentDirectory(), \"InputFileForRunCommand.txt\");\n            string parseResultSections = \"run \" + pathToScript;\n\n            ArrangeInputs(parseResultSections: parseResultSections,\n                 out MockedShellState _,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult,\n                 caretPosition: 7);\n\n            IShellState shellState = GetShellState(string.Empty, httpState);\n            MockedFileSystem mockedFileSystem = new MockedFileSystem();\n            mockedFileSystem.AddFile(pathToScript, string.Empty);\n\n            RunCommand runCommand = new RunCommand(mockedFileSystem);\n            IEnumerable<string> result = runCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.NotEmpty(result);\n        }\n\n        private IShellState GetShellState(string inputBuffer, HttpState httpState)\n        {\n            DefaultCommandDispatcher<HttpState> defaultCommandDispatcher = DefaultCommandDispatcher.Create(x => { }, httpState);\n            defaultCommandDispatcher.AddCommand(new SetHeaderCommand(new NullTelemetry()));\n\n            Mock<IConsoleManager> mockConsoleManager = new Mock<IConsoleManager>();\n            MockInputManager mockInputManager = new MockInputManager(inputBuffer);\n\n            ShellState shellState = new ShellState(defaultCommandDispatcher,\n                consoleManager: mockConsoleManager.Object,\n                commandHistory: new CommandHistory(),\n                inputManager: mockInputManager);\n\n            Shell shell = new Shell(shellState);\n\n            return shell.ShellState;\n        }\n\n        public void Dispose()\n        {\n            if (File.Exists(_pathToScript))\n            {\n                File.Delete(_pathToScript);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/SetHeaderCommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.OpenApi;\nusing Microsoft.HttpRepl.Telemetry;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class SetHeaderCommandTests : CommandTestsBase\n    {\n        [Fact]\n        public void CanHandle_WithParseResultSectionsLessThanTwo_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"set\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            bool? result = setHeaderCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithFirstParseResultSectionNotEqualToName_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"test header name\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            bool? result = setHeaderCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithSecondParseResultSectionNotEqualToSubCommand_ReturnsNull()\n        {\n            ArrangeInputs(parseResultSections: \"set base name\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            bool? result = setHeaderCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithValidInput_ReturnsTrue()\n        {\n            ArrangeInputs(parseResultSections: \"set header name\",\n                out MockedShellState shellState,\n                out HttpState httpState,\n                out ICoreParseResult parseResult);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            bool? result = setHeaderCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.True(result);\n        }\n\n        [Fact]\n        public void GetHelpSummary_ReturnsDescription()\n        {\n            ArrangeInputs(parseResultSections: string.Empty,\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult _);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            string result = setHeaderCommand.GetHelpSummary(shellState, httpState);\n\n            Assert.Equal(SetHeaderCommand.Description, result);\n        }\n\n        [Fact]\n        public void GetHelpDetails_ReturnsHelpDetails()\n        {\n            ArrangeInputs(parseResultSections: \"set header\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            string expected = \"\\u001b[1mUsage: \\u001b[39mset header {name} [value]\" + Environment.NewLine + Environment.NewLine + \"Sets or clears a header. When [value] is empty the header is cleared.\" + Environment.NewLine;\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            string result = setHeaderCommand.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithExactlyThreeValidParseResultSections_DoesNotUpdateHeaders()\n        {\n            ArrangeInputs(parseResultSections: \"set header test\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            await setHeaderCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Dictionary<string, IEnumerable<string>> headers = httpState.Headers;\n            KeyValuePair<string, IEnumerable<string>> firstHeader = headers.First();\n\n            Assert.Single(httpState.Headers);\n            Assert.Equal(\"User-Agent\", firstHeader.Key);\n            Assert.Equal(\"HTTP-REPL\", firstHeader.Value.First());\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithMoreThanThreeValidParseResultSections_AddsEntryToHeaders()\n        {\n            ArrangeInputs(parseResultSections: \"set header name value1 value2\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            await setHeaderCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Dictionary<string, IEnumerable<string>> headers = httpState.Headers;\n\n            Assert.Equal(2, httpState.Headers.Count);\n\n            Assert.True(headers.ContainsKey(\"User-Agent\"));\n            Assert.True(headers.ContainsKey(\"name\"));\n\n            headers.TryGetValue(\"User-Agent\", out IEnumerable<string> userAgentHeaderValues);\n            headers.TryGetValue(\"name\", out IEnumerable<string> nameHeaderValues);\n\n            Assert.Contains(\"HTTP-REPL\", userAgentHeaderValues);\n            Assert.Contains(\"value1\", nameHeaderValues);\n            Assert.Contains(\"value2\", nameHeaderValues);\n        }\n\n        [Fact]\n        public void Suggest_WithNoParseResultSections_ReturnsName()\n        {\n            ArrangeInputs(parseResultSections: string.Empty,\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            IEnumerable<string> suggestions = setHeaderCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.Single(suggestions);\n            Assert.Equal(\"set\", suggestions.First());\n        }\n\n        [Fact]\n        public void Suggest_WithOneParseResultSectionAndSelectedSectionGreaterAtZero_ReturnsName()\n        {\n            ArrangeInputs(parseResultSections: \"set\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult,\n                 caretPosition: 0);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            IEnumerable<string> suggestions = setHeaderCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.Single(suggestions);\n            Assert.Equal(\"set\", suggestions.First());\n        }\n\n        [Fact]\n        public void Suggest_WithOneParseResultSectionAndSelectedSectionGreaterThanZero_ReturnsName()\n        {\n            ArrangeInputs(parseResultSections: \"set\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult,\n                 caretPosition: 3);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            IEnumerable<string> suggestions = setHeaderCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.Single(suggestions);\n            Assert.Equal(\"set\", suggestions.First());\n        }\n\n        [Fact]\n        public void Suggest_WithMoreThanOneParseResultSectionAndSelectedSectionGreaterThanZero_ReturnsName()\n        {\n            ArrangeInputs(parseResultSections: \"set header\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult,\n                 caretPosition: 10);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            IEnumerable<string> suggestions = setHeaderCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.Single(suggestions);\n            Assert.Equal(\"header\", suggestions.First());\n        }\n\n        [Fact]\n        public void Suggest_WithMoreThanTwoParseResultSectionsAndSelectedSectionGreaterThanTwo_ReturnsHeaderCompletion()\n        {\n            ArrangeInputs(parseResultSections: \"set header O\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult,\n                 caretPosition: 12);\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            IEnumerable<string> suggestions = setHeaderCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.Single(suggestions);\n            Assert.Equal(\"Origin\", suggestions.First());\n        }\n\n        [Fact]\n        public void Suggest_WithMoreThanThreeParseResultSectionsAndSelectedSectionAtThree_ReturnsValueCompletion()\n        {\n            ArrangeInputs(parseResultSections: \"set header CONTENT-TYPE t\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult,\n                 caretPosition: 25);\n\n            IDirectoryStructure directoryStructure = GetDirectoryStructure(\"testMethod\", \"testContentType\", \"testBody\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = directoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n            httpState.BaseAddress = new Uri(\"http://localhost:5050/\");\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            List<string> suggestions = setHeaderCommand.Suggest(shellState, httpState, parseResult).ToList();\n\n            Assert.Single(suggestions);\n            Assert.Equal(\"testContentType\", suggestions.First());\n        }\n\n        [Fact]\n        public void Suggest_WithMoreThanThreeParseResultSectionsAndNoMatchingCompletions_ReturnsNothing()\n        {\n            ArrangeInputs(parseResultSections: \"set header CONTENT-TYPE z\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult,\n                 caretPosition: 25);\n\n            IDirectoryStructure directoryStructure = GetDirectoryStructure(\"testMethod\", \"testContentType\", \"testBody\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = directoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n            httpState.BaseAddress = new Uri(\"http://localhost:5050/\");\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(new NullTelemetry());\n            IEnumerable<string> suggestions = setHeaderCommand.Suggest(shellState, httpState, parseResult);\n\n            Assert.Empty(suggestions);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithKnownHeader_SendsTelemetryWithHeaderName()\n        {\n            ArrangeInputs(parseResultSections: \"set header Authorization value\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            TelemetryCollector telemetry = new TelemetryCollector();\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(telemetry);\n            await setHeaderCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(telemetry.Telemetry);\n            TelemetryCollector.CollectedTelemetry collectedTelemetry = telemetry.Telemetry[0];\n            Assert.Equal(\"SetHeader\", collectedTelemetry.EventName);\n            Assert.Equal(\"Authorization\", collectedTelemetry.Properties[\"HeaderName\"]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[\"IsValueEmpty\"]);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithUnknownHeader_SendsTelemetryWithHashedHeaderName()\n        {\n            ArrangeInputs(parseResultSections: \"set header name value\",\n                 out MockedShellState shellState,\n                 out HttpState httpState,\n                 out ICoreParseResult parseResult);\n\n            TelemetryCollector telemetry = new TelemetryCollector();\n\n            SetHeaderCommand setHeaderCommand = new SetHeaderCommand(telemetry);\n            await setHeaderCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Single(telemetry.Telemetry);\n            TelemetryCollector.CollectedTelemetry collectedTelemetry = telemetry.Telemetry[0];\n            Assert.Equal(\"SetHeader\", collectedTelemetry.EventName);\n            Assert.Equal(Sha256Hasher.Hash(\"name\"), collectedTelemetry.Properties[\"HeaderName\"]);\n            Assert.Equal(\"False\", collectedTelemetry.Properties[\"IsValueEmpty\"]);\n        }\n\n        private IDirectoryStructure GetDirectoryStructure(string method, string contentType, string body)\n        {\n            RequestInfo requestInfo = new RequestInfo();\n            requestInfo.SetRequestBody(method, contentType, body);\n\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            DirectoryStructure childDirectoryStructure = directoryStructure.DeclareDirectory(contentType);\n            childDirectoryStructure.RequestInfo = requestInfo;\n\n            return childDirectoryStructure;\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/TreeNodeTests.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.txt file in the project root for more information.\n\nusing System;\nusing Microsoft.HttpRepl.Commands;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class TreeNodeTests\n    {\n        [Fact]\n        public void Constructor_WithNullFormatter_ThrowsArgumentNullException()\n        {\n            Formatter formatter = null;\n            string prefix = \"\";\n            string entry = \"\";\n\n            Assert.Throws<ArgumentNullException>(() => new TreeNode(formatter, prefix, entry));\n        }\n\n        [Fact]\n        public void Constructor_WithNullPrefix_ThrowsArgumentNullException()\n        {\n            Formatter formatter = new Formatter();\n            string prefix = null;\n            string entry = \"\";\n\n            Assert.Throws<ArgumentNullException>(() => new TreeNode(formatter, prefix, entry));\n        }\n\n        [Fact]\n        public void AddChild_WithNullPrefix_ThrowsArgumentNullException()\n        {\n            Formatter parentFormatter = new Formatter();\n            string parentPrefix = \"\";\n            string parentEntry = \"\";\n            TreeNode treeNode = new TreeNode(parentFormatter, parentPrefix, parentEntry);\n            string childPrefix = null;\n            string childEntry = \"\";\n\n            Assert.Throws<ArgumentNullException>(() => treeNode.AddChild(childPrefix, childEntry));\n        }\n\n        [Fact]\n        public void AddChild_Valid_ReturnedChildAddedToChildren()\n        {\n            Formatter parentFormatter = new Formatter();\n            string parentPrefix = \"\";\n            string parentEntry = \"\";\n            TreeNode treeNode = new TreeNode(parentFormatter, parentPrefix, parentEntry);\n            string childPrefix = \"\";\n            string childEntry = \"\";\n\n            TreeNode childTreeNode = treeNode.AddChild(childPrefix, childEntry);\n\n            Assert.Contains(childTreeNode, treeNode.Children);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Commands/UICommandTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Commands;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Resources;\nusing Microsoft.HttpRepl.UserProfile;\nusing Microsoft.Repl.Parsing;\nusing Moq;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Commands\n{\n    public class UICommandTests : CommandTestsBase\n    {\n        [Fact]\n        public void CanHandle_WithNoParseResultSections_ReturnsNull()\n        {\n            ArrangeInputs(commandText: string.Empty,\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            UICommand uiCommand = new UICommand(new UriLauncher(), preferences);\n\n            bool? result = uiCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithMoreThanOneParseResultSections_ReturnsTrue()\n        {\n            ArrangeInputs(commandText: \"ui test\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            UICommand uiCommand = new UICommand(new UriLauncher(), preferences);\n\n            bool? result = uiCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.True(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithInvalidName_ReturnsNull()\n        {\n            ArrangeInputs(commandText: \"test\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            UICommand uiCommand = new UICommand(new UriLauncher(), preferences);\n\n            bool? result = uiCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void CanHandle_WithValidName_ReturnsTrue()\n        {\n            ArrangeInputs(commandText: \"ui\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            UICommand uiCommand = new UICommand(new UriLauncher(), preferences);\n\n            bool? result = uiCommand.CanHandle(shellState, httpState, parseResult);\n\n            Assert.True(result);\n        }\n\n        [Fact]\n        public void GetHelpSummary_ReturnsHelpSummary()\n        {\n            ArrangeInputs(commandText: string.Empty,\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out _,\n                          out _,\n                          out IPreferences preferences);\n\n            UICommand uiCommand = new UICommand(new UriLauncher(), preferences);\n\n            string result = uiCommand.GetHelpSummary(shellState, httpState);\n\n            Assert.Equal(Strings.UICommand_HelpSummary, result);\n        }\n\n        [Fact]\n        public void GetHelpDetails_WithInvalidParseResultSection_ReturnsNull()\n        {\n            ArrangeInputs(commandText: \"section1\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            UICommand uiCommand = new UICommand(new UriLauncher(), preferences);\n\n            string result = uiCommand.GetHelpDetails(shellState, httpState, parseResult);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithHttpStateBaseAddressSetToNull_WritesToConsoleManagerError()\n        {\n            MockedShellState shellState = new MockedShellState();\n            ICoreParseResult parseResult = CoreParseResultHelper.Create(\"ui\");\n            HttpState httpState = GetHttpState(out _, out IPreferences preferences);\n            httpState.BaseAddress = null;\n\n            Mock<IUriLauncher> mockLauncher = new Mock<IUriLauncher>();\n            UICommand uiCommand = new UICommand(mockLauncher.Object, preferences);\n\n            await uiCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            VerifyErrorMessageWasWrittenToConsoleManagerError(shellState);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithValidHttpStateBaseAddress_VerifyLaunchUriAsyncWasCalledOnce()\n        {\n            ArrangeInputs(commandText: \"ui\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            Uri uri = new Uri(\"https://localhost:44366/\");\n            httpState.BaseAddress = uri;\n\n            Mock<IUriLauncher> mockLauncher = new Mock<IUriLauncher>();\n            UICommand uiCommand = new UICommand(mockLauncher.Object, preferences);\n\n            mockLauncher.Setup(s => s.LaunchUriAsync(It.IsAny<Uri>()))\n                .Returns(Task.CompletedTask);\n\n            await uiCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            mockLauncher.Verify(l => l.LaunchUriAsync(It.Is<Uri>(u => u.AbsoluteUri == \"https://localhost:44366/swagger\")), Times.Once());\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithLaunchUriFailure_ThrowsException()\n        {\n            ArrangeInputs(commandText: \"ui\",\n                          baseAddress: null,\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            Uri uri = new Uri(\"https://localhost:44366/\");\n            httpState.BaseAddress = uri;\n\n            Mock<IUriLauncher> mockLauncher = new Mock<IUriLauncher>();\n            string expectedErrorMessage = \"Unable to launch https://localhost:44366/swagger\";\n            mockLauncher.Setup(s => s.LaunchUriAsync(It.IsAny<Uri>()))\n                .Returns(Task.FromException(new Exception(expectedErrorMessage)));\n\n            UICommand uiCommand = new UICommand(mockLauncher.Object, preferences);\n            var exception = await Record.ExceptionAsync(async () => await uiCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None));\n\n            Assert.NotNull(exception);\n            Assert.Equal(expectedErrorMessage, exception.Message);\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithRelativeParameter_VerifyLaunchUriAsyncWasCalledOnce()\n        {\n            ArrangeInputs(commandText: \"ui /mySwaggerPath\",\n                          baseAddress: \"https://localhost:44366/\",\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            Mock<IUriLauncher> mockLauncher = new Mock<IUriLauncher>();\n            UICommand uiCommand = new UICommand(mockLauncher.Object, preferences);\n\n            mockLauncher.Setup(s => s.LaunchUriAsync(It.IsAny<Uri>()))\n                        .Returns(Task.CompletedTask);\n\n            await uiCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            mockLauncher.Verify(l => l.LaunchUriAsync(It.Is<Uri>(u => u.AbsoluteUri == \"https://localhost:44366/mySwaggerPath\")), Times.Once());\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithAbsoluteParameter_VerifyLaunchUriAsyncWasCalledOnce()\n        {\n            ArrangeInputs(commandText: \"ui https://localhost:12345/mySwaggerPath\",\n                          baseAddress: \"https://localhost:44366/\",\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            Mock<IUriLauncher> mockLauncher = new Mock<IUriLauncher>();\n            UICommand uiCommand = new UICommand(mockLauncher.Object, preferences);\n\n            mockLauncher.Setup(s => s.LaunchUriAsync(It.IsAny<Uri>()))\n                        .Returns(Task.CompletedTask);\n\n            await uiCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            mockLauncher.Verify(l => l.LaunchUriAsync(It.Is<Uri>(u => u.AbsoluteUri == \"https://localhost:12345/mySwaggerPath\")), Times.Once());\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoParameterAndNoPreference_VerifyLaunchUriAsyncWasCalledOnce()\n        {\n            ArrangeInputs(commandText: \"ui\",\n                          baseAddress: \"https://localhost:44366/\",\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            Mock<IUriLauncher> mockLauncher = new Mock<IUriLauncher>();\n            UICommand uiCommand = new UICommand(mockLauncher.Object, preferences);\n\n            mockLauncher.Setup(s => s.LaunchUriAsync(It.IsAny<Uri>()))\n                        .Returns(Task.CompletedTask);\n\n            await uiCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            mockLauncher.Verify(l => l.LaunchUriAsync(It.Is<Uri>(u => u.AbsoluteUri == \"https://localhost:44366/swagger\")), Times.Once());\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoParameterAndRelativePreference_VerifyLaunchUriAsyncWasCalledOnce()\n        {\n            string commandText = \"ui\";\n            ICoreParseResult parseResult = CoreParseResultHelper.Create(commandText);\n            MockedShellState shellState = new MockedShellState();\n            MockedFileSystem fileSystem = new MockedFileSystem();\n            UserFolderPreferences preferences = new UserFolderPreferences(fileSystem, new UserProfileDirectoryProvider(), null);\n            preferences.SetValue(WellKnownPreference.SwaggerUIEndpoint, \"/mySwaggerPath\");\n            HttpState httpState = new HttpState(preferences, new HttpClient());\n            httpState.BaseAddress = new Uri(\"https://localhost:44366\", UriKind.Absolute);\n\n            Mock<IUriLauncher> mockLauncher = new Mock<IUriLauncher>();\n            UICommand uiCommand = new UICommand(mockLauncher.Object, preferences);\n\n            mockLauncher.Setup(s => s.LaunchUriAsync(It.IsAny<Uri>()))\n                        .Returns(Task.CompletedTask);\n\n            await uiCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            mockLauncher.Verify(l => l.LaunchUriAsync(It.Is<Uri>(u => u.AbsoluteUri == \"https://localhost:44366/mySwaggerPath\")), Times.Once());\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithNoParameterAndAbsolutePreference_VerifyLaunchUriAsyncWasCalledOnce()\n        {\n            string commandText = \"ui\";\n            ICoreParseResult parseResult = CoreParseResultHelper.Create(commandText);\n            MockedShellState shellState = new MockedShellState();\n            MockedFileSystem fileSystem = new MockedFileSystem();\n            UserFolderPreferences preferences = new UserFolderPreferences(fileSystem, new UserProfileDirectoryProvider(), null);\n            preferences.SetValue(WellKnownPreference.SwaggerUIEndpoint, \"https://localhost:12345/mySwaggerPath\");\n            HttpState httpState = new HttpState(preferences, new HttpClient());\n            httpState.BaseAddress = new Uri(\"https://localhost:44366\", UriKind.Absolute);\n\n            Mock<IUriLauncher> mockLauncher = new Mock<IUriLauncher>();\n            UICommand uiCommand = new UICommand(mockLauncher.Object, preferences);\n\n            mockLauncher.Setup(s => s.LaunchUriAsync(It.IsAny<Uri>()))\n                        .Returns(Task.CompletedTask);\n\n            await uiCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            mockLauncher.Verify(l => l.LaunchUriAsync(It.Is<Uri>(u => u.AbsoluteUri == \"https://localhost:12345/mySwaggerPath\")), Times.Once());\n        }\n\n        [Fact]\n        public async Task ExecuteAsync_WithInvalidParameterAndNoPreference_DisplaysError()\n        {\n            string invalidParameter = \"https:///localhost/swagger\";\n            string expectedError = string.Format(Strings.UICommand_InvalidParameter, invalidParameter);\n            ArrangeInputs(commandText: $\"ui {invalidParameter}\",\n                          baseAddress: \"https://localhost:44366/\",\n                          path: null,\n                          urlsWithResponse: null,\n                          out MockedShellState shellState,\n                          out HttpState httpState,\n                          out ICoreParseResult parseResult,\n                          out _,\n                          out IPreferences preferences);\n\n            Mock<IUriLauncher> mockLauncher = new Mock<IUriLauncher>();\n            UICommand uiCommand = new UICommand(mockLauncher.Object, preferences);\n\n            await uiCommand.ExecuteAsync(shellState, httpState, parseResult, CancellationToken.None);\n\n            Assert.Equal(expectedError, shellState.ErrorMessage, StringComparer.Ordinal);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/FileSystem/RealFileSystemTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.IO;\nusing Microsoft.HttpRepl.FileSystem;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.FileSystem\n{\n    public class RealFileSystemTests\n    {\n        [Theory]\n        [InlineData(\".json\")]\n        [InlineData(\".xml\")]\n        [InlineData(\".tmp\")]\n        [InlineData(\".a\")]\n        public void GetTempFileName_WithValidInput_ReturnsFileNameWithExtension(string extension)\n        {\n            RealFileSystem realFileSystem = new RealFileSystem();\n\n            string fullName = realFileSystem.GetTempFileName(extension);\n\n            Assert.NotNull(fullName);\n            Assert.EndsWith(extension, fullName, StringComparison.OrdinalIgnoreCase);\n        }\n\n        [Theory]\n        [InlineData(\".json\")]\n        [InlineData(\".xml\")]\n        [InlineData(\".tmp\")]\n        [InlineData(\".a\")]\n        public void GetTempFileName_WithValidInput_ReturnsFileInTempPath(string extension)\n        {\n            RealFileSystem realFileSystem = new RealFileSystem();\n            string expectedPath = Path.GetTempPath();\n\n            string actualPath = realFileSystem.GetTempFileName(extension);\n\n            Assert.StartsWith(expectedPath, actualPath, StringComparison.OrdinalIgnoreCase);\n        }\n\n        [Theory]\n        [InlineData(\".json\")]\n        [InlineData(\".xml\")]\n        [InlineData(\".tmp\")]\n        [InlineData(\".a\")]\n        public void GetTempFileName_WithValidInput_ReturnsFileThatStartsWithHttpRepl(string extension)\n        {\n            RealFileSystem realFileSystem = new RealFileSystem();\n            string expectedStart = \"HttpRepl.\";\n\n            string fullName = realFileSystem.GetTempFileName(extension);\n            string actualFileName = Path.GetFileName(fullName);\n\n            Assert.StartsWith(expectedStart, actualFileName, StringComparison.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetTempFileName_WithNullExtension_ThrowsArgumentNullException()\n        {\n            RealFileSystem realFileSystem = new RealFileSystem();\n\n            Assert.Throws<ArgumentNullException>(() => realFileSystem.GetTempFileName(null));\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\".\")]\n        [InlineData(\",a\")]\n        public void GetTEmpFileName_WithInvalidInput_ThrowsArgumentException(string extension)\n        {\n            RealFileSystem realFileSystem = new RealFileSystem();\n\n            Assert.Throws<ArgumentException>(() => realFileSystem.GetTempFileName(extension));\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/HttpStateTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.OpenApi;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.UserProfile;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests\n{\n    public class HttpStateTests\n    {\n        [Fact]\n        public void GetRelativePathString_EmptyPathSections_Slash()\n        {\n            string expected = \"/\";\n            HttpState state = SetupHttpState();\n            state.PathSections.Clear();\n\n            string result = state.GetRelativePathString();\n\n            Assert.Equal(expected, result);\n        }\n\n        [Fact]\n        public void GetRelativePathString_SinglePathSection_CorrectString()\n        {\n            string expected = \"/FirstDirectory\";\n            HttpState state = SetupHttpState();\n            state.PathSections.Push(\"FirstDirectory\");\n\n            string result = state.GetRelativePathString();\n\n            Assert.Equal(expected, result);\n        }\n\n        [Fact]\n        public void GetRelativePathString_MultiplePathSections_CorrectString()\n        {\n            string expected = \"/FirstDirectory/SecondDirectory\";\n            HttpState state = SetupHttpState();\n            state.PathSections.Push(\"FirstDirectory\");\n            state.PathSections.Push(\"SecondDirectory\");\n\n            string result = state.GetRelativePathString();\n\n            Assert.Equal(expected, result);\n        }\n\n        [Fact]\n        public void GetApplicableContentTypes_NoBaseAddress_ReturnsNull()\n        {\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = null;\n\n            IEnumerable<string> result = httpState.GetApplicableContentTypes(null, string.Empty);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void GetApplicableContentTypes_NoStructure_ReturnsNull()\n        {\n            HttpState httpState = SetupHttpState();\n\n            httpState.BaseAddress = new Uri(\"https://localhost/\");\n            httpState.ApiDefinition = null;\n\n            IEnumerable<string> result = httpState.GetApplicableContentTypes(null, string.Empty);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void GetApplicableContentTypes_NoMethod_ReturnsAll()\n        {\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            RequestInfo requestInfo = new RequestInfo();\n            requestInfo.SetRequestBody(\"GET\", \"application/json\", \"\");\n            requestInfo.SetRequestBody(\"PUT\", \"application/xml\", \"\");\n            directoryStructure.RequestInfo = requestInfo;\n\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = new Uri(\"https://localhost/\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = directoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n\n            IEnumerable<string> result = httpState.GetApplicableContentTypes(null, \"\");\n\n            Assert.NotNull(result);\n\n            Assert.Equal(2, result.Count());\n            Assert.Contains(\"application/json\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"application/xml\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetApplicableContentTypes_GetMethod_ReturnsCorrectOne()\n        {\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            RequestInfo requestInfo = new RequestInfo();\n            requestInfo.SetRequestBody(\"GET\", \"application/json\", \"\");\n            requestInfo.SetRequestBody(\"PUT\", \"application/xml\", \"\");\n            directoryStructure.RequestInfo = requestInfo;\n\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = new Uri(\"https://localhost/\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = directoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n\n            IEnumerable<string> result = httpState.GetApplicableContentTypes(\"GET\", \"\");\n\n            Assert.Single(result);\n            Assert.Contains(\"application/json\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetApplicableContentTypes_WithPath_ReturnsCorrectOne()\n        {\n            DirectoryStructure parentDirectoryStructure = new DirectoryStructure(null);\n            RequestInfo parentRequestInfo = new RequestInfo();\n            parentRequestInfo.SetRequestBody(\"GET\", \"application/json\", \"\");\n            parentDirectoryStructure.RequestInfo = parentRequestInfo;\n            DirectoryStructure childDirectoryStructure = parentDirectoryStructure.DeclareDirectory(\"child\");\n            RequestInfo childRequestInfo = new RequestInfo();\n            childRequestInfo.SetRequestBody(\"GET\", \"application/xml\", \"\");\n            childDirectoryStructure.RequestInfo = childRequestInfo;\n\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = new Uri(\"https://localhost/\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = parentDirectoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n\n            IEnumerable<string> result = httpState.GetApplicableContentTypes(\"GET\", \"child\");\n\n            Assert.Single(result);\n            Assert.Contains(\"application/xml\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetEffectivePath_NoBaseAddressOrAbsoluteUri_ThrowsArgumentNullException()\n        {\n            Assert.Throws<ArgumentNullException>(() => HttpState.GetEffectivePath(null, \"\", \"/NotAnAbsoluteUri\", queryParam: null));\n        }\n\n        [Theory]\n        [InlineData(\"https://github.com/\", \"\", \"https://localhost/pets\", \"https://localhost/pets\")]\n        [InlineData(\"https://localhost/\", \"dir1\", \"dir2\", \"https://localhost/dir1/dir2\")]\n        [InlineData(\"https://localhost/\", \"dir1?q=5&r=6\", \"dir2?s=7\", \"https://localhost/dir1/dir2?q=5&r=6&s=7\")]\n        [InlineData(\"https://petstore.swagger.io/v2/\", \"pet\", \"\", \"https://petstore.swagger.io/v2/pet\")]\n        [InlineData(\"https://petstore.swagger.io/v2/\", \"/pet\", \"\", \"https://petstore.swagger.io/pet\")]\n        [InlineData(\"https://petstore.swagger.io/v2/\", \"\", \"pet\", \"https://petstore.swagger.io/v2/pet\")]\n        [InlineData(\"https://petstore.swagger.io/v2/\", \"\", \"/pet\", \"https://petstore.swagger.io/pet\")]\n        [InlineData(\"https://petstore.swagger.io/v2/\", \"/pet\", \"/buy\", \"https://petstore.swagger.io/buy\")]\n        [InlineData(\"https://petstore.swagger.io/\", \"pet\", \"\", \"https://petstore.swagger.io/pet\")]\n        [InlineData(\"https://petstore.swagger.io/\", \"/pet\", \"\", \"https://petstore.swagger.io/pet\")]\n        [InlineData(\"https://petstore.swagger.io/\", \"\", \"pet\", \"https://petstore.swagger.io/pet\")]\n        [InlineData(\"https://petstore.swagger.io/\", \"\", \"/pet\", \"https://petstore.swagger.io/pet\")]\n        public void GetEffectivePath_ProperConcatenation(string baseUriString, string pathSections, string specifiedPath, string expectedResult)\n        {\n            Uri baseUri = new Uri(baseUriString);\n\n            Uri result = HttpState.GetEffectivePath(baseUri, pathSections, specifiedPath, queryParam: null);\n\n            Assert.Equal(expectedResult, result.ToString(), StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetEffectivePath_AppendQueryString_SingleCase()\n        {\n            string baseUriString = \"https://github.com/\";\n            string pathSections = \"dir1\";\n            string specifiedPath = \"dir2\";\n            var queryString = new Dictionary<string, IEnumerable<string>>()\n            {\n                [\"key\"] = new List<string>() { \"value\"}\n            };\n            Uri baseUri = new Uri(baseUriString);\n\n            Uri result = HttpState.GetEffectivePath(baseUri, pathSections, specifiedPath, queryString);\n\n            Assert.Equal(\"https://github.com/dir1/dir2?key=value\", result.ToString(), StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetEffectivePath_AppendQueryString_MultipleCase()\n        {\n            string baseUriString = \"https://github.com/\";\n            string pathSections = \"dir1\";\n            string specifiedPath = \"dir2\";\n            var queryString = new Dictionary<string, IEnumerable<string>>()\n            {\n                [\"key1\"] = new List<string>() { \"value\" },\n                [\"key2\"] = new List<string>() { \"value\" },\n            };\n            Uri baseUri = new Uri(baseUriString);\n\n            Uri result = HttpState.GetEffectivePath(baseUri, pathSections, specifiedPath, queryString);\n\n            Assert.Equal(\"https://github.com/dir1/dir2?key1=value&key2=value\", result.ToString(), StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetEffectivePath_AppendQueryString_Multiple_SameKey()\n        {\n            string baseUriString = \"https://github.com/\";\n            string pathSections = \"dir1\";\n            string specifiedPath = \"dir2\";\n            var queryString = new Dictionary<string, IEnumerable<string>>()\n            {\n                [\"key1\"] = new List<string>() { \"value\", \"anotherValue\" },\n            };\n            Uri baseUri = new Uri(baseUriString);\n\n            Uri result = HttpState.GetEffectivePath(baseUri, pathSections, specifiedPath, queryString);\n\n            Assert.Equal(\"https://github.com/dir1/dir2?key1=value&key1=anotherValue\", result.ToString(), StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetEffectivePath_AppendQueryString_EncodeUriValues ()\n        {\n            string baseUriString = \"https://github.com/\";\n            string pathSections = \"dir1\";\n            string specifiedPath = \"dir2\";\n            var queryString = new Dictionary<string, IEnumerable<string>>()\n            {\n                [\"key1\"] = new List<string>() { \"a+b=c\" },\n            };\n            Uri baseUri = new Uri(baseUriString);\n\n            Uri result = HttpState.GetEffectivePath(baseUri, pathSections, specifiedPath, queryString);\n\n            Assert.Equal(\"https://github.com/dir1/dir2?key1=a%2Bb%3Dc\", result.ToString(), StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetEffectivePath_AppendQueryString_EncodeUriKeys ()\n        {\n            string baseUriString = \"https://github.com/\";\n            string pathSections = \"dir1\";\n            string specifiedPath = \"dir2\";\n            var queryString = new Dictionary<string, IEnumerable<string>>()\n            {\n                [\"a+b=c\"] = new List<string>() { \"value1\" },\n            };\n            Uri baseUri = new Uri(baseUriString);\n\n            Uri result = HttpState.GetEffectivePath(baseUri, pathSections, specifiedPath, queryString);\n\n            Assert.Equal(\"https://github.com/dir1/dir2?a%2Bb%3Dc=value1\", result.ToString(), StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetEffectivePath_NullBaseAddressAndNoPath_Throws()\n        {\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = null;\n\n            Assert.Throws<ArgumentNullException>(\"baseAddress\", () => httpState.GetEffectivePathWithoutQueryParam(\"\"));\n        }\n\n        [Fact]\n        public void GetEffectivePathForPrompt_NullBaseAddress_ReturnsNull()\n        {\n            HttpState httpState = SetupHttpState();\n\n            httpState.BaseAddress = null;\n\n            Uri result = httpState.GetEffectivePathForPrompt();\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void HeaderSetup_WithDefaultUserAgent_UsesHttpRepl()\n        {\n            HttpState httpState = SetupHttpState(preferencesFileContent: \"\");\n\n            Assert.Equal(\"HTTP-REPL\", httpState.Headers[\"User-Agent\"].Single(), StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public void HeaderSetup_WithCustomUserAgent_UsesCustom()\n        {\n            string differentUserAgent = \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3875.0 Safari/537.36 Edg/78.0.245.0\";\n\n            HttpState httpState = SetupHttpState(preferencesFileContent: $\"{WellKnownPreference.HttpClientUserAgent}={differentUserAgent}\");\n\n            Assert.Equal(differentUserAgent, httpState.Headers[\"User-Agent\"].Single(), StringComparer.Ordinal);\n        }\n\n        private static HttpState SetupHttpState(string preferencesFileContent = null)\n        {\n            UserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            IFileSystem fileSystem;\n            if (preferencesFileContent != null)\n            {\n                fileSystem = new MockedFileSystem();\n            }\n            else\n            {\n                fileSystem = new FileSystemStub();\n            }\n            UserFolderPreferences preferences = new UserFolderPreferences(fileSystem, userProfileDirectoryProvider, null);\n            if (preferencesFileContent != null)\n            {\n                ((MockedFileSystem)fileSystem).AddFile(preferences.PreferencesFilePath, preferencesFileContent);\n            }\n\n            HttpClient client = new HttpClient();\n            HttpState state = new HttpState(preferences, client);\n\n            return state;\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/JsonVisitorTests.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.Formatting;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.Repl.ConsoleHandling;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests\n{\n    public class JsonVisitorTests\n    {\n        [Fact]\n        public void JsonVisitor_ObjectWithComments()\n        {\n            string testData = @\"[\n    {\n        //Object 1\n        \"\"property\"\": \"\"value\"\",\n        \"\"and\"\": \"\"again\"\"\n    },\n    {\n        //Object 2\n    },\n    [\n        //An array\n    ],\n    null,\n    1,\n    3.2,\n    \"\"test\"\",\n    false\n]\";\n\n            string formatted = JsonVisitor.FormatAndColorize(new MockJsonConfig(), testData);\n        }\n\n        private class MockJsonConfig : IJsonConfig\n        {\n            public int IndentSize => 2;\n\n            public AllowedColors DefaultColor => AllowedColors.None;\n\n            public AllowedColors ArrayBraceColor => AllowedColors.None;\n\n            public AllowedColors ObjectBraceColor => AllowedColors.None;\n\n            public AllowedColors CommaColor => AllowedColors.None;\n\n            public AllowedColors NameColor => AllowedColors.None;\n\n            public AllowedColors NameSeparatorColor => AllowedColors.None;\n\n            public AllowedColors BoolColor => AllowedColors.None;\n\n            public AllowedColors NumericColor => AllowedColors.None;\n\n            public AllowedColors StringColor => AllowedColors.None;\n\n            public AllowedColors NullColor => AllowedColors.None;\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Microsoft.HttpRepl.Tests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>$(TestProjectTargetFramework)</TargetFramework>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <EmbeddedResource Include=\"Resources\\OpenApiDescriptions\\MicrosoftGraph.PowershellSdk.Analytics.json\" />\n    <EmbeddedResource Include=\"Resources\\OpenApiDescriptions\\MicrosoftGraph.PowershellSdk.Analytics.yml\" />\n    <EmbeddedResource Include=\"Resources\\OpenApiDescriptions\\MicrosoftGraph.PowershellSdk.CloudCommunications.json\" />\n    <EmbeddedResource Include=\"Resources\\OpenApiDescriptions\\MicrosoftGraph.PowershellSdk.CloudCommunications.yml\" />\n    <EmbeddedResource Include=\"Resources\\OpenApiDescriptions\\MicrosoftGraph.PowershellSdk.Subscriptions.json\" />\n    <EmbeddedResource Include=\"Resources\\OpenApiDescriptions\\MicrosoftGraph.PowershellSdk.Subscriptions.yml\" />\n    <EmbeddedResource Include=\"Resources\\OpenApiDescriptions\\xkcd.json\" />\n    <EmbeddedResource Include=\"Resources\\OpenApiDescriptions\\xkcd.yml\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Moq\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"Newtonsoft.Json\" PrivateAssets=\"All\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"$(RepoSource)\\Microsoft.HttpRepl\\Microsoft.HttpRepl.csproj\" />\n    <ProjectReference Include=\"$(RepoTest)\\Microsoft.HttpRepl.Fakes\\Microsoft.HttpRepl.Fakes.csproj\" />\n    <ProjectReference Include=\"$(RepoSource)\\Microsoft.Repl\\Microsoft.Repl.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/OpenApi/ApiDefinitionBuilder.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing Microsoft.HttpRepl.OpenApi;\n\nnamespace Microsoft.HttpRepl.Tests.OpenApi\n{\n    internal class ApiDefinitionBuilder\n    {\n        private readonly List<ApiDefinitionBaseAddress> _baseAddresses = new();\n        private readonly List<DirectoryBuilder<ApiDefinitionBuilder>> _directories = new();\n\n        private ApiDefinitionBuilder() { }\n\n        public static ApiDefinitionBuilder Start() => new ApiDefinitionBuilder();\n\n        public ApiDefinitionBuilder AddBaseAddress(string url, string description)\n        {\n            _baseAddresses.Add(new ApiDefinitionBaseAddress(url, description));\n            return this;\n        }\n\n        public DirectoryBuilder<ApiDefinitionBuilder> AddDirectory(string directory)\n        {\n            DirectoryBuilder<ApiDefinitionBuilder> directoryBuilder = new(this, directory);\n            _directories.Add(directoryBuilder);\n            return directoryBuilder;\n        }\n\n        public ApiDefinition Build()\n        {\n            ApiDefinition apiDefinition = new();\n            apiDefinition.DirectoryStructure = new DirectoryStructure(null);\n\n            foreach (ApiDefinitionBaseAddress baseAddress in _baseAddresses)\n            {\n                apiDefinition.BaseAddresses.Add(new ApiDefinition.Server() { Url = baseAddress.Url, Description = baseAddress.Description });\n            }\n\n            foreach (DirectoryBuilder<ApiDefinitionBuilder> subDirectoryBuilder in _directories)\n            {\n                DirectoryStructure subdirectory = ((DirectoryStructure)apiDefinition.DirectoryStructure).DeclareDirectory(subDirectoryBuilder.Name);\n                BuildDirectory(subDirectoryBuilder, subdirectory);\n            }\n\n            return apiDefinition;\n        }\n\n        private void BuildDirectory<T>(DirectoryBuilder<T> directoryBuilder, DirectoryStructure directoryStructure)\n        {\n            if (directoryBuilder.Methods.Count > 0)\n            {\n                RequestInfo requestInfo = new();\n\n                foreach (string method in directoryBuilder.Methods)\n                {\n                    requestInfo.AddMethod(method);\n                }\n\n                directoryStructure.RequestInfo = requestInfo;\n            }\n\n            foreach (DirectoryBuilder<DirectoryBuilder<T>> subDirectoryBuilder in directoryBuilder.Directories)\n            {\n                DirectoryStructure subdirectory = directoryStructure.DeclareDirectory(subDirectoryBuilder.Name);\n                BuildDirectory(subDirectoryBuilder, subdirectory);\n            }\n        }\n\n        private class ApiDefinitionBaseAddress\n        {\n            public ApiDefinitionBaseAddress(string url, string description)\n            {\n                Url = new Uri(url);\n                Description = description;\n            }\n\n            public Uri Url { get; }\n            public string Description { get; }\n        }\n\n        internal class DirectoryBuilder<T>\n        {\n            private T _parent;\n            private List<DirectoryBuilder<DirectoryBuilder<T>>> _directories = new();\n            private List<string> _methods = new();\n\n            public DirectoryBuilder(T parent, string name)\n            {\n                _parent = parent;\n                Name = name;\n            }\n\n            public IReadOnlyList<DirectoryBuilder<DirectoryBuilder<T>>> Directories => _directories;\n            public IReadOnlyList<string> Methods => _methods;\n            public string Name { get; }\n\n            public DirectoryBuilder<DirectoryBuilder<T>> AddDirectory(string directory)\n            {\n                DirectoryBuilder<DirectoryBuilder<T>> directoryBuilder = new(this, directory);\n                _directories.Add(directoryBuilder);\n                return directoryBuilder;\n            }\n\n            public DirectoryBuilder<T> AddMethod(string method)\n            {\n                _methods.Add(method);\n                return this;\n            }\n\n            public DirectoryBuilder<T> WithGet()\n            {\n                return AddMethod(\"Get\");\n            }\n\n            public DirectoryBuilder<T> WithPost()\n            {\n                return AddMethod(\"Post\");\n            }\n\n            public DirectoryBuilder<T> WithPatch()\n            {\n                return AddMethod(\"Patch\");\n            }\n\n            public DirectoryBuilder<T> WithDelete()\n            {\n                return AddMethod(\"Delete\");\n            }\n\n            public T Finalize()\n            {\n                return _parent;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/OpenApi/ApiDefinitionReaderTests.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.txt file in the project root for more information.\n\nusing System;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.OpenApi;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.OpenApi\n{\n    public class ApiDefinitionReaderTests\n    {\n        [Fact]\n        public void Read_WithJObjectFormatNotSupportedByAnyExistingReader_ReturnsNull()\n        {\n            string json = @\"{\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\",\n    \"\"title\"\": \"\"My API\"\"\n  }\n}\";\n\n            ApiDefinitionReader apiDefinitionReader = new ApiDefinitionReader();\n\n            ApiDefinitionParseResult result = apiDefinitionReader.Read(json, null);\n\n            Assert.False(result.Success);\n        }\n\n        [Fact]\n        public void RegisterReader_AddNewReader_VerifyReadReturnsApiDefinitionWithStructure()\n        {\n            string json = @\"{\n  \"\"fakeApi\"\": \"\"1.0.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  }\n}\";\n\n            ApiDefinition apiDefinition = new ApiDefinition() { DirectoryStructure = new DirectoryStructure(null) };\n            ApiDefinitionReaderStub apiDefinitionReaderStub = new ApiDefinitionReaderStub(apiDefinition);\n\n            ApiDefinitionReader reader = new ApiDefinitionReader();\n            reader.RegisterReader(apiDefinitionReaderStub);\n\n            ApiDefinitionParseResult result = reader.Read(json, null);\n\n            Assert.Same(apiDefinition, result.ApiDefinition);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/OpenApi/OpenApiDotNetApiDefinitionReaderTests.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Reflection;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.OpenApi;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.OpenApi\n{\n    public class OpenApiDotNetApiDefinitionReaderTests\n    {\n        [Theory]\n        [MemberData(nameof(GetYamlResourcePaths), MemberType = typeof(OpenApiDotNetApiDefinitionReaderTests))]\n        [MemberData(nameof(GetJsonResourcePaths), MemberType = typeof(OpenApiDotNetApiDefinitionReaderTests))]\n        public async Task CanHandle_RealOpenApiDescriptions_ReturnsNotNull(string resourcePath)\n        {\n            // Arrange\n            string content = await GetResourceContent(resourcePath);\n            OpenApiDotNetApiDefinitionReader apiDefinitionReader = new();\n\n            // Act\n            ApiDefinitionParseResult actual = apiDefinitionReader.CanHandle(content);\n\n            // Assert\n            Assert.True(actual.Success);\n        }\n\n        [Theory]\n        [MemberData(nameof(GetYamlTestSetups), MemberType = typeof(OpenApiDotNetApiDefinitionReaderTests))]\n        [MemberData(nameof(GetJsonTestSetups), MemberType = typeof(OpenApiDotNetApiDefinitionReaderTests))]\n        public async Task ReadDefinition_RealOpenApiDescriptions_ReturnsExpectedDocument(string resourcePath, ApiDefinition expected)\n        {\n            // Arrange\n            string content = await GetResourceContent(resourcePath);\n            OpenApiDotNetApiDefinitionReader apiDefinitionReader = new();\n\n            // Act\n            ApiDefinitionParseResult actual = apiDefinitionReader.ReadDefinition(content, null);\n\n            // Assert\n            AssertDefinition(expected, actual.ApiDefinition);\n        }\n\n        [Fact]\n        public void CanHandle_WithMissingInfoAndPaths_ReturnsValidationMessages()\n        {\n            // Arrange\n            string json = @\"\n{\n  \"\"openapi\"\": \"\"3.0.0\"\"\n}\n\";\n            OpenApiDotNetApiDefinitionReader apiDefinitionReader = new();\n\n            // Act\n            ApiDefinitionParseResult result = apiDefinitionReader.CanHandle(json);\n\n            // Assert\n            Assert.True(result.Success);\n            Assert.NotEmpty(result.ValidationMessages);\n        }\n\n        private void AssertDefinition(ApiDefinition expected, ApiDefinition actual)\n        {\n            // Core properties\n            Assert.NotNull(actual);\n            Assert.NotNull(actual.BaseAddresses);\n            Assert.NotNull(actual.DirectoryStructure);\n\n            // Base Addresses/Servers\n            IEnumerator<ApiDefinition.Server> expectedBaseAddressEnumerator = expected.BaseAddresses.GetEnumerator();\n            IEnumerator<ApiDefinition.Server> actualBaseAddressEnumerator = actual.BaseAddresses.GetEnumerator();\n\n            int index = 0;\n            while (expectedBaseAddressEnumerator.MoveNext())\n            {\n                Assert.True(actualBaseAddressEnumerator.MoveNext(), $\"Missing BaseAddress: {expectedBaseAddressEnumerator.Current}\");\n\n                Assert.True(expectedBaseAddressEnumerator.Current.Url == actualBaseAddressEnumerator.Current.Url, $\"BaseAddress[{index}].Url does not match.\");\n                Assert.True(string.Equals(expectedBaseAddressEnumerator.Current.Description, actualBaseAddressEnumerator.Current.Description, System.StringComparison.InvariantCulture), $\"BaseAddress[{index}].Description does not match.\");\n\n                index++;\n            }\n            Assert.False(actualBaseAddressEnumerator.MoveNext(), $\"Extra BaseAddress: {actualBaseAddressEnumerator.Current}\");\n\n            // Directory Structure\n            AssertDirectoryStructure(expected.DirectoryStructure, actual.DirectoryStructure, \"/\");\n        }\n\n        private void AssertDirectoryStructure(IDirectoryStructure expected, IDirectoryStructure actual, string path)\n        {\n            // Request Info/Methods\n            if (expected.RequestInfo is null)\n            {\n                Assert.True(actual.RequestInfo is null, $\"RequestInfo should be null on {path}\");\n            }\n            else\n            {\n                AssertRequestInfo(expected.RequestInfo, actual.RequestInfo, path);\n            }\n\n            // Subdirectories\n            IEnumerator<string> expectedDirectoriesEnumerator = expected.DirectoryNames.GetEnumerator();\n            IEnumerator<string> actualDirectoriesEnumerator = actual.DirectoryNames.GetEnumerator();\n\n            int directoryIndex = 0;\n            while (expectedDirectoriesEnumerator.MoveNext())\n            {\n                Assert.True(actualDirectoriesEnumerator.MoveNext(), $\"Missing subdirectory in {path}: {expectedDirectoriesEnumerator.Current}\");\n                Assert.True(string.Equals(expectedDirectoriesEnumerator.Current, actualDirectoriesEnumerator.Current, System.StringComparison.Ordinal), $\"Expected Directory \\\"{expectedDirectoriesEnumerator.Current}\\\" does not match Actual Directory \\\"{actualDirectoriesEnumerator.Current}\\\" at index {directoryIndex} in {path}.\");\n\n                AssertDirectoryStructure(expected.TraverseTo(expectedDirectoriesEnumerator.Current), actual.TraverseTo(actualDirectoriesEnumerator.Current), $\"{path}{expectedDirectoriesEnumerator.Current}/\");\n\n                directoryIndex++;\n            }\n\n            // Something changed in recent .NET SDKs such that one of these is happening:\n            // 1) The message is being calculated eagerly when it was not before (thus calculating it even when MoveNext returns false)\n            // 2) Current now throws if there is no current, whereas before it did not\n            // #2 is more likely, but I can't prove it in the sources. We'll break out the Assert.False and do the if check\n            // and message construction separately to avoid it.\n            //Assert.False(actualDirectoriesEnumerator.MoveNext(), $\"Extra subdirectory in {path}: {actualDirectoriesEnumerator.Current}\");\n\n            if (actualDirectoriesEnumerator.MoveNext())\n            {\n                Assert.Fail($\"Extra subdirectory in {path}: {actualDirectoriesEnumerator.Current}\");\n            }\n\n        }\n\n        private void AssertRequestInfo(IRequestInfo expected, IRequestInfo actual, string path)\n        {\n            // Core object\n            Assert.True(actual is not null, $\"RequestInfo should NOT be null on {path}\");\n\n            // Methods\n            IEnumerator<string> expectedMethodsEnumerator = expected.Methods.GetEnumerator();\n            IEnumerator<string> actualMethodsEnumerator = actual.Methods.GetEnumerator();\n\n            int methodIndex = 0;\n            while (expectedMethodsEnumerator.MoveNext())\n            {\n                Assert.True(actualMethodsEnumerator.MoveNext(), $\"Missing method in {path}: {expectedMethodsEnumerator.Current}\");\n\n                Assert.True(string.Equals(expectedMethodsEnumerator.Current, actualMethodsEnumerator.Current, System.StringComparison.Ordinal), $\"Expected Method \\\"{expectedMethodsEnumerator.Current}\\\" does not match Actual Method \\\"{actualMethodsEnumerator.Current}\\\" at index {methodIndex} in {path}.\");\n\n                methodIndex++;\n            }\n            Assert.False(actualMethodsEnumerator.MoveNext(), $\"Extra method in {path}: {actualMethodsEnumerator.Current}\");\n        }\n\n\n        private async Task<string> GetResourceContent(string filePath)\n        {\n            Assembly assembly = Assembly.GetExecutingAssembly();\n            string resourcePath = assembly.GetName().Name + \".Resources.\" + filePath.Replace('\\\\', '.');\n            using (Stream resourceStream = assembly.GetManifestResourceStream(resourcePath))\n            using (StreamReader reader = new(resourceStream))\n            {\n                return await reader.ReadToEndAsync();\n            }\n        }\n\n        public static IEnumerable<object[]> GetJsonTestSetups()\n        {\n            return GetTestSetups(\".json\");\n        }\n\n        public static IEnumerable<object[]> GetYamlTestSetups()\n        {\n            return GetTestSetups(\".yml\");\n        }\n\n        public static IEnumerable<object[]> GetJsonResourcePaths()\n        {\n            return GetResourcePaths(\".json\");\n        }\n\n        public static IEnumerable<object[]> GetYamlResourcePaths()\n        {\n            return GetResourcePaths(\".yml\");\n        }\n\n        private static IEnumerable<string[]> GetResourcePaths(string extension)\n        {\n            foreach (string resourcePath in ResourcePaths)\n            {\n                yield return new[] { resourcePath + extension };\n            }\n        }\n\n        private static string[] ResourcePaths = new[]\n        {\n            \"OpenApiDescriptions\\\\MicrosoftGraph.PowershellSdk.Subscriptions\",\n            \"OpenApiDescriptions\\\\MicrosoftGraph.PowershellSdk.Analytics\",\n            \"OpenApiDescriptions\\\\MicrosoftGraph.PowershellSdk.CloudCommunications\",\n            \"OpenApiDescriptions\\\\xkcd\",\n        };\n\n        private static IEnumerable<object[]> GetTestSetups(string extension)\n        {\n            int x = 0;\n            yield return new object[]\n            {\n                ResourcePaths[x++] + extension,\n                ApiDefinitionBuilder.Start()\n                                    .AddBaseAddress(\"https://graph.microsoft.com/v1.0/\", \"Core\")\n                                    .AddDirectory(\"subscriptions\")\n                                        .WithGet()\n                                        .WithPost()\n                                        .AddDirectory(\"{subscription-id}\")\n                                            .WithGet()\n                                            .WithPatch()\n                                            .WithDelete()\n                                            .Finalize()\n                                        .Finalize()\n                                    .Build()\n            };\n\n            yield return new object[]\n            {\n                ResourcePaths[x++] + extension,\n                ApiDefinitionBuilder.Start()\n                                    .AddBaseAddress(\"https://graph.microsoft.com/v1.0/\", \"Core\")\n                                    .AddDirectory(\"users\")\n                                    .AddDirectory(\"{user-id}\")\n                                        .AddDirectory(\"insights\")\n                                            .WithGet()\n                                            .WithPatch()\n                                            .AddDirectory(\"shared\")\n                                                .WithGet()\n                                                .WithPost()\n                                                .AddDirectory(\"{sharedInsight-id}\")\n                                                    .WithGet()\n                                                    .WithPatch()\n                                                    .AddDirectory(\"lastSharedMethod\")\n                                                        .WithGet()\n                                                        .Finalize()\n                                                    .AddDirectory(\"resource\")\n                                                        .WithGet()\n                                                        .Finalize()\n                                                    .Finalize()\n                                                .Finalize()\n                                            .AddDirectory(\"trending\")\n                                                .WithGet()\n                                                .WithPost()\n                                                .AddDirectory(\"{trending-id}\")\n                                                    .WithGet()\n                                                    .WithPatch()\n                                                    .AddDirectory(\"resource\")\n                                                        .WithGet()\n                                                        .Finalize()\n                                                    .Finalize()\n                                                .Finalize()\n                                            .AddDirectory(\"used\")\n                                                .WithGet()\n                                                .WithPost()\n                                                .AddDirectory(\"{usedInsight-id}\")\n                                                    .WithGet()\n                                                    .WithPatch()\n                                                    .AddDirectory(\"resource\")\n                                                        .WithGet()\n                                                        .Finalize()\n                                                    .Finalize()\n                                                .Finalize()\n                                            .Finalize()\n                                        .Finalize()\n                                    .Finalize()\n                                    .Build()\n            };\n            yield return new object[]\n            {\n                ResourcePaths[x++] + extension,\n                ApiDefinitionBuilder.Start()\n                                    .AddBaseAddress(\"https://graph.microsoft.com/v1.0/\", \"Core\")\n                                    .AddDirectory(\"communications\")\n                                        .WithGet()\n                                        .WithPatch()\n                                        .AddDirectory(\"calls\")\n                                            .WithGet()\n                                            .WithPost()\n                                            .AddDirectory(\"{call-id}\")\n                                                .WithGet()\n                                                .WithPatch()\n                                                .AddDirectory(\"microsoft.graph.answer\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.changeScreenSharingRole\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.keepAlive\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.mute\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.playPrompt\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.recordResponse\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.redirect\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.reject\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.subscribeToTone\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.transfer\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.unmute\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"microsoft.graph.updateRecordingStatus\")\n                                                    .WithPost()\n                                                    .Finalize()\n                                                .AddDirectory(\"operations\")\n                                                    .WithGet()\n                                                    .WithPost()\n                                                    .AddDirectory(\"{commsOperation-id}\")\n                                                        .WithGet()\n                                                        .WithPatch()\n                                                        .Finalize()\n                                                    .Finalize()\n                                                .AddDirectory(\"participants\")\n                                                    .WithGet()\n                                                    .WithPost()\n                                                    .AddDirectory(\"{participant-id}\")\n                                                        .WithGet()\n                                                        .WithPatch()\n                                                        .AddDirectory(\"microsoft.graph.mute\")\n                                                            .WithPost()\n                                                            .Finalize()\n                                                        .Finalize()\n                                                    .AddDirectory(\"microsoft.graph.invite\")\n                                                        .WithPost()\n                                                        .Finalize()\n                                                    .Finalize()\n                                                .Finalize()\n                                            .AddDirectory(\"microsoft.graph.logTeleconferenceDeviceQuality\")\n                                                .WithPost()\n                                                .Finalize()\n                                            .Finalize()\n                                        .AddDirectory(\"onlineMeetings\")\n                                            .WithGet()\n                                            .WithPost()\n                                            .AddDirectory(\"{onlineMeeting-id}\")\n                                                .WithGet()\n                                                .WithPatch()\n                                                .Finalize()\n                                            .Finalize()\n                                        .Finalize()\n                                    .Build()\n            };\n            yield return new object[]\n            {\n                ResourcePaths[x++] + extension,\n                ApiDefinitionBuilder.Start()\n                                    .AddBaseAddress(\"http://xkcd.com\", null)\n                                    .AddDirectory(\"info.0.json\")\n                                        .WithGet()\n                                        .Finalize()\n                                    .AddDirectory(\"{comicId}\")\n                                        .AddDirectory(\"info.0.json\")\n                                            .WithGet()\n                                            .Finalize()\n                                        .Finalize()\n                                    .Build()\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/OpenApi/OpenApiDotNetApiDefinitionReaderV2Tests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Linq;\nusing Microsoft.HttpRepl.OpenApi;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.OpenApi\n{\n    public class OpenApiDotNetApiDefinitionReaderV2Tests\n    {\n        [Fact]\n        public void ReadMetadata_WithNoPaths_ReturnsApiDefinitionWithNoDirectories()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Empty(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithNoProperties_ReturnsApiDefinitionWithNoDirectories()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Empty(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithNoRequestMethods_ReturnsApiDefinitionWithNullRequestInfo()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/api/Employees\"\": {\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, null);\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/api/Employees\");\n\n            Assert.Null(subDirectory.RequestInfo);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithNoRequestMethods_ReturnsApiDefinitionWithStructure()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/api/Employees\"\": {\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithValidInput_ReturnsApiDefinition()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/api/Employees\"\": {\n      \"\"get\"\": {\n        \"\"tags\"\": [\n          \"\"Employees\"\"\n        ],\n        \"\"operationId\"\": \"\"GetEmployee\"\",\n        \"\"consumes\"\": [],\n        \"\"produces\"\": [\n          \"\"text/plain\"\"\n        ],\n        \"\"parameters\"\": [],\n        \"\"responses\"\": {\n          \"\"200\"\": {\n            \"\"description\"\": \"\"Success\"\"\n          }\n        }\n      },\n      \"\"post\"\": {\n        \"\"tags\"\": [\n          \"\"Employees\"\"\n        ],\n        \"\"operationId\"\": \"\"put\"\",\n        \"\"consumes\"\": [],\n        \"\"produces\"\": [\n          \"\"text/plain\"\"\n        ],\n        \"\"parameters\"\": [\n          {\n            \"\"name\"\": \"\"id\"\",\n            \"\"in\"\": \"\"path\"\"\n          }\n        ],\n        \"\"responses\"\": {\n          \"\"200\"\": {\n            \"\"description\"\": \"\"Success\"\"\n          }\n        }\n      }\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n            Assert.Equal(\"api\", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single());\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/api/Employees\");\n\n            Assert.Equal(2, subDirectory.RequestInfo.Methods.Count);\n            Assert.Contains(\"Get\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n            Assert.Contains(\"Post\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public void CanHandle_WithNoSwaggerVersionKeyInDocument_ReturnsFalse()\n        {\n            string json = @\"{\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v? Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.CanHandle(json);\n\n            Assert.False(result.Success);\n        }\n\n        [Fact]\n        public void CanHandle_WithValidSwaggerVersionKeyInDocument_ReturnsTrue()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v2 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.CanHandle(json);\n\n            Assert.True(result.Success);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithNoHost_BaseAddressesIsEmpty()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri(\"http://localhost/swagger.json\"));\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Empty(result.ApiDefinition.BaseAddresses);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithHostAndOneScheme_BaseAddressesHasOneEntry()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"host\"\": \"\"localhost\"\",\n  \"\"schemes\"\": [\n    \"\"https\"\"\n  ],\n  \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri(\"http://localhost/swagger.json\"));\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Single(result.ApiDefinition.BaseAddresses);\n            Assert.Equal(\"https://localhost/\", result.ApiDefinition.BaseAddresses[0].Url.ToString(), StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithHostAndTwoSchemes_BaseAddressesHasTwoEntries()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"host\"\": \"\"localhost\"\",\n  \"\"schemes\"\": [\n    \"\"https\"\",\n    \"\"http\"\"\n  ],\n  \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri(\"http://localhost/swagger.json\"));\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Equal(2, result.ApiDefinition.BaseAddresses.Count);\n            Assert.Equal(\"https://localhost/\", result.ApiDefinition.BaseAddresses[0].Url.ToString(), StringComparer.Ordinal);\n            Assert.Equal(\"http://localhost/\", result.ApiDefinition.BaseAddresses[1].Url.ToString(), StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithHostAndNoScheme_BaseAddressesHasOneEntryWithSchemeFromSourceUri()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"host\"\": \"\"localhost\"\",\n  \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri(\"https://localhost/swagger.json\"));\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Single(result.ApiDefinition.BaseAddresses);\n            Assert.Equal(\"https://localhost/\", result.ApiDefinition.BaseAddresses[0].Url.ToString(), StringComparer.Ordinal);\n\n            result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri(\"http://localhost/swagger.json\"));\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Single(result.ApiDefinition.BaseAddresses);\n            Assert.Equal(\"http://localhost/\", result.ApiDefinition.BaseAddresses[0].Url.ToString(), StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithHostAndBaseAndScheme_BaseAddressesHasOneEntry()\n        {\n            string json = @\"{\n  \"\"swagger\"\": \"\"2.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"host\"\": \"\"localhost\"\",\n  \"\"basePath\"\": \"\"/api/v2\"\",\n  \"\"schemes\"\": [\n    \"\"https\"\"\n  ],\n  \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader swaggerV2ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = swaggerV2ApiDefinitionReader.ReadDefinition(json, new Uri(\"http://localhost/swagger.json\"));\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Single(result.ApiDefinition.BaseAddresses);\n            Assert.Equal(\"https://localhost/api/v2/\", result.ApiDefinition.BaseAddresses[0].Url.ToString(), StringComparer.Ordinal);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/OpenApi/OpenApiDotNetApiDefinitionReaderV3Tests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Linq;\nusing Microsoft.HttpRepl.OpenApi;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.OpenApi\n{\n    public class OpenApiDotNetApiDefinitionReaderV3Tests\n    {\n        [Fact]\n        public void ReadMetadata_WithNoPaths_ReturnsEmptyDirectoryStructure()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Empty(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithNoProperties_ReturnsNullDirectoryStructure()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n   \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Empty(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithNoResponses_ReturnsApiDefinition()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n      \"\"post\"\": {\n        \"\"summary\"\": \"\"Create a pet\"\",\n        \"\"operationId\"\": \"\"createPets\"\",\n        \"\"requestBody\"\": {\n          \"\"content\"\": {\n\n          }\n        }\n      }\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n            Assert.Equal(\"pets\", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single());\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/pets\");\n\n            Assert.Single(subDirectory.RequestInfo.Methods);\n            Assert.Contains(\"Post\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithNoMethods_ReturnsApiDefinitionWithStructure()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithNoResponses_ReturnsApiDefinitionWithNoRequestInfo()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/pets\");\n\n            Assert.Null(subDirectory.RequestInfo);\n        }\n\n        [Theory]\n        [InlineData(\"Get\", true)]\n        [InlineData(\"Post\", true)]\n        [InlineData(\"Put\", true)]\n        [InlineData(\"Delete\", true)]\n        [InlineData(\"Options\", true)]\n        [InlineData(\"Head\", true)]\n        [InlineData(\"Patch\", true)]\n        [InlineData(\"Trace\", true)]\n        [InlineData(\"$ref\", false)]\n        [InlineData(\"summary\", false)]\n        [InlineData(\"description\", false)]\n        [InlineData(\"servers\", false)]\n        [InlineData(\"parameters\", false)]\n        [InlineData(\"\", false)]\n        public void ReadMetadata_WithSpecifiedMethodName_ReturnsApiDefinitionWithCorrectNumberOfRequestMethods(string method, bool shouldHaveRequest)\n        {\n            // The method must be lowercase to be valid in the json\n            string methodForJson = method.ToLower();\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n      \"\"\" + methodForJson + @\"\"\": {\n        \"\"summary\"\": \"\"Do something\"\",\n        \"\"operationId\"\": \"\"doSomething\"\",\n        \"\"responses\"\": {\n          \"\"200\"\": {\n            \"\"description\"\": \"\"Null response\"\"\n          }\n        },\n        \"\"requestBody\"\": {\n          \"\"description\"\": \"\"A Request Body\"\",\n          \"\"required\"\": false\n        }\n      }\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n            Assert.Equal(\"pets\", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single());\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/pets\");\n\n            if (shouldHaveRequest)\n            {\n                Assert.Single(subDirectory.RequestInfo.Methods);\n                Assert.Contains(method, subDirectory.RequestInfo.Methods, StringComparer.OrdinalIgnoreCase);\n            }\n            else\n            {\n                Assert.Null(subDirectory.RequestInfo);\n            }\n        }\n\n        [Fact]\n        public void ReadMetadata_WithNoContent_ReturnsApiDefinitionWithRequestMethodButNoContentTypes()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n      \"\"post\"\": {\n        \"\"summary\"\": \"\"Create a pet\"\",\n        \"\"operationId\"\": \"\"createPets\"\",\n        \"\"responses\"\": {\n          \"\"201\"\": {\n            \"\"description\"\": \"\"Null response\"\"\n          }\n        },\n        \"\"requestBody\"\": {\n          \"\"description\"\": \"\"A Request Body\"\",\n          \"\"required\"\": false\n        }\n      }\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n            Assert.Equal(\"pets\", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single());\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/pets\");\n\n            Assert.Single(subDirectory.RequestInfo.Methods);\n            Assert.Contains(\"Post\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n            Assert.DoesNotContain(\"post\", subDirectory.RequestInfo.ContentTypesByMethod.Keys, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithContentAndOneContentType_ReturnsApiDefinitionWithContentType()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n      \"\"post\"\": {\n        \"\"summary\"\": \"\"Create a pet\"\",\n        \"\"operationId\"\": \"\"createPets\"\",\n        \"\"responses\"\": {\n          \"\"201\"\": {\n            \"\"description\"\": \"\"Null response\"\"\n          }\n        },\n        \"\"requestBody\"\": {\n          \"\"description\"\": \"\"A Request Body\"\",\n          \"\"required\"\": false,\n          \"\"content\"\": {\n            \"\"application/json\"\": {\n            }\n          }\n        }\n      }\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n            Assert.Equal(\"pets\", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single());\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/pets\");\n\n            Assert.Single(subDirectory.RequestInfo.Methods);\n            Assert.Contains(\"Post\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n            Assert.Single(subDirectory.RequestInfo.ContentTypesByMethod[\"post\"]);\n            Assert.Contains(\"application/json\", subDirectory.RequestInfo.ContentTypesByMethod[\"post\"]);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithContentAndMultipleContentTypes_ReturnsApiDefinitionWithContentTypes()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n      \"\"post\"\": {\n        \"\"summary\"\": \"\"Create a pet\"\",\n        \"\"operationId\"\": \"\"createPets\"\",\n        \"\"responses\"\": {\n          \"\"201\"\": {\n            \"\"description\"\": \"\"Null response\"\"\n          }\n        },\n        \"\"requestBody\"\": {\n          \"\"description\"\": \"\"A Request Body\"\",\n          \"\"required\"\": false,\n          \"\"content\"\": {\n            \"\"application/json\"\": {\n            },\n            \"\"text/plain\"\": {\n            }\n          }\n        }\n      }\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n            Assert.Equal(\"pets\", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single());\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/pets\");\n\n            Assert.Single(subDirectory.RequestInfo.Methods);\n            Assert.Contains(\"Post\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n            Assert.Equal(2, subDirectory.RequestInfo.ContentTypesByMethod[\"post\"].Count);\n            Assert.Contains(\"application/json\", subDirectory.RequestInfo.ContentTypesByMethod[\"post\"]);\n            Assert.Contains(\"text/plain\", subDirectory.RequestInfo.ContentTypesByMethod[\"post\"]);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithValidInput_ReturnsApiDefinition()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n      \"\"get\"\": {\n        \"\"summary\"\": \"\"List all pets\"\",\n        \"\"operationId\"\": \"\"listPets\"\",\n        \"\"parameters\"\": [\n          {\n            \"\"name\"\": \"\"limit\"\",\n            \"\"in\"\": \"\"query\"\",\n            \"\"required\"\": false,\n            \"\"schema\"\": {\n              \"\"type\"\": \"\"integer\"\",\n              \"\"format\"\": \"\"int32\"\"\n            }\n          }\n        ],\n        \"\"responses\"\": {\n          \"\"200\"\": {\n            \"\"description\"\": \"\"An paged array of pets\"\"\n          }\n        }\n      },\n      \"\"post\"\": {\n        \"\"summary\"\": \"\"Create a pet\"\",\n        \"\"operationId\"\": \"\"createPets\"\",\n        \"\"responses\"\": {\n          \"\"201\"\": {\n            \"\"description\"\": \"\"Null response\"\"\n          }\n        },\n        \"\"requestBody\"\": {\n          \"\"content\"\": {\n\n          }\n        }\n      }\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n            Assert.Equal(\"pets\", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single());\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/pets\");\n\n            Assert.Equal(2, subDirectory.RequestInfo.Methods.Count);\n            Assert.Contains(\"Get\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n            Assert.Contains(\"Post\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public void ReadMetadata_WithNoRequestBody_ReturnsApiDefinition()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n      \"\"get\"\": {\n        \"\"responses\"\": {\n          \"\"200\"\": {\n            \"\"description\"\": \"\"Success\"\"\n          }\n        }\n      },\n      \"\"post\"\": {\n        \"\"summary\"\": \"\"Create a pet\"\",\n        \"\"operationId\"\": \"\"createPets\"\",\n        \"\"responses\"\": {\n          \"\"201\"\": {\n            \"\"description\"\": \"\"Null response\"\"\n          }\n        },\n        \"\"requestBody\"\": {\n          \"\"content\"\": {\n\n          }\n        }\n      }\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.DirectoryStructure);\n            Assert.Single(result.ApiDefinition.DirectoryStructure.DirectoryNames);\n            Assert.Equal(\"pets\", result.ApiDefinition.DirectoryStructure.DirectoryNames.Single());\n\n            IDirectoryStructure subDirectory = result.ApiDefinition.DirectoryStructure.TraverseTo(\"/pets\");\n\n            Assert.Equal(2, subDirectory.RequestInfo.Methods.Count);\n            Assert.Contains(\"Get\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n            Assert.Contains(\"Post\", subDirectory.RequestInfo.Methods, StringComparer.Ordinal);\n        }\n\n        [Fact]\n        public void CanHandle_WithNoOpenApiKeyInDocument_ReturnsFalse()\n        {\n            string json = @\"{\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v? Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n   \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.CanHandle(json);\n\n            Assert.False(result.Success);\n        }\n\n        [Fact]\n        public void CanHandle_WithValidOpenApiVersionInDocument_ReturnsTrue()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v3 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n   \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.CanHandle(json);\n\n            Assert.True(result.Success);\n        }\n\n        [Fact]\n        public void CanHandle_WithOpenApiVersionGreaterThanThree_ReturnsFalse()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"4.0.0\"\",\n  \"\"info\"\": {\n    \"\"title\"\": \"\"OpenAPI v4 Spec\"\",\n    \"\"version\"\": \"\"v1\"\"\n  },\n   \"\"paths\"\": {\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.CanHandle(json);\n\n            Assert.False(result.Success);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithNoServers_BaseAddressesIsEmpty()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Empty(result.ApiDefinition.BaseAddresses);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithOneServer_BaseAddressesHasOneEntry()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"https://localhost/\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Single(result.ApiDefinition.BaseAddresses);\n            Assert.Equal(\"https://localhost/\", result.ApiDefinition.BaseAddresses[0].Url.ToString());\n            Assert.Equal(\"First Server Address\", result.ApiDefinition.BaseAddresses[0].Description);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithTwoServers_BaseAddressesHasTwoEntries()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"https://petstore.swagger.io/\"\",\n      \"\"description\"\": \"\"Production Server Address\"\"\n    },\n    {\n      \"\"url\"\": \"\"https://localhost/\"\",\n      \"\"description\"\": \"\"Local Development Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, null);\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Equal(2, result.ApiDefinition.BaseAddresses.Count);\n\n            Assert.Equal(\"https://petstore.swagger.io/\", result.ApiDefinition.BaseAddresses[0].Url.ToString());\n            Assert.Equal(\"Production Server Address\", result.ApiDefinition.BaseAddresses[0].Description);\n\n            Assert.Equal(\"https://localhost/\", result.ApiDefinition.BaseAddresses[1].Url.ToString());\n            Assert.Equal(\"Local Development Server Address\", result.ApiDefinition.BaseAddresses[1].Description);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithRelativeServer_BaseAddressesCorrectEntry()\n        {\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"servers\"\": [\n    {\n      \"\"url\"\": \"\"/api/v2\"\",\n      \"\"description\"\": \"\"First Server Address\"\"\n    }\n  ],\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n    }\n  }\n}\";\n\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, new Uri(\"https://localhost/swagger.json\"));\n\n            Assert.NotNull(result.ApiDefinition?.BaseAddresses);\n            Assert.Single(result.ApiDefinition.BaseAddresses);\n            Assert.Equal(\"https://localhost/api/v2/\", result.ApiDefinition.BaseAddresses[0].Url.ToString());\n            Assert.Equal(\"First Server Address\", result.ApiDefinition.BaseAddresses[0].Description);\n        }\n\n        [Fact]\n        public void ReadDefinition_WithRequestBody_SchemaIsIncluded()\n        {\n            string contentType = \"application/json\";\n            string json = @\"{\n  \"\"openapi\"\": \"\"3.0.0\"\",\n  \"\"info\"\": {\n    \"\"version\"\": \"\"v1\"\"\n  },\n  \"\"paths\"\": {\n    \"\"/pets\"\": {\n      \"\"post\"\": {\n        \"\"requestBody\"\": {\n          \"\"content\"\": {\n            \"\"\" + contentType + @\"\"\": {\n              \"\"schema\"\": {\n                \"\"type\"\": \"\"object\"\",\n                \"\"properties\"\": {\n                  \"\"date\"\": {\n                    \"\"type\"\": \"\"string\"\",\n                    \"\"format\"\": \"\"date-time\"\"\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\";\n\n            OpenApiDotNetApiDefinitionReader openApiV3ApiDefinitionReader = new OpenApiDotNetApiDefinitionReader();\n\n            ApiDefinitionParseResult result = openApiV3ApiDefinitionReader.ReadDefinition(json, new Uri(\"https://localhost/swagger.json\"));\n            IDirectoryStructure pets = result.ApiDefinition.DirectoryStructure.TraverseTo(\"pets\");\n            string requestBody = pets.RequestInfo.GetRequestBodyForContentType(ref contentType, \"post\");\n\n            Assert.NotNull(requestBody);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/OpenApi/SchemaDataGeneratorTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.HttpRepl.OpenApi;\nusing Microsoft.OpenApi;\nusing Microsoft.OpenApi.Any;\nusing Microsoft.OpenApi.Models;\nusing Microsoft.OpenApi.Writers;\nusing Newtonsoft.Json.Linq;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.OpenApi\n{\n    public class SchemaDataGeneratorTests\n    {\n        [Fact]\n        public void GenerateData_WithNull_ReturnsNull()\n        {\n            JToken result = SchemaDataGenerator.GenerateData(null);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void GenerateData_WithExample_ReturnsJTokenBasedOnExample()\n        {\n            string stringValue = \"string value\";\n            int intValue = 5;\n            OpenApiSchema schema = new OpenApiSchema();\n            schema.Example = new StringAndIntClass() { StringProperty = stringValue, IntProperty = intValue,};\n\n            JToken result = SchemaDataGenerator.GenerateData(schema);\n\n            Assert.NotNull(result);\n            Assert.NotNull(result[\"StringProperty\"]);\n            Assert.Equal(stringValue, result[\"StringProperty\"].Value<string>());\n            Assert.NotNull(result[\"IntProperty\"]);\n            Assert.Equal(intValue, result[\"IntProperty\"].Value<int>());\n        }\n\n        [Fact]\n        public void GenerateData_WithDefault_ReturnsJTokenBasedOnDefault()\n        {\n            string stringValue = \"string value\";\n            int intValue = 5;\n            OpenApiSchema schema = new OpenApiSchema();\n            schema.Default = new StringAndIntClass() { StringProperty = stringValue, IntProperty = intValue };\n\n            JToken result = SchemaDataGenerator.GenerateData(schema);\n\n            Assert.NotNull(result);\n            Assert.NotNull(result[\"StringProperty\"]);\n            Assert.Equal(stringValue, result[\"StringProperty\"].Value<string>());\n            Assert.NotNull(result[\"IntProperty\"]);\n            Assert.Equal(intValue, result[\"IntProperty\"].Value<int>());\n        }\n\n        [Fact]\n        public void GenerateData_WithExampleAndDefault_ReturnsJTokenBasedOnExample()\n        {\n            string stringValue = \"string value\";\n            int intValue = 5;\n            OpenApiSchema schema = new OpenApiSchema();\n            schema.Example = new StringAndIntClass() { StringProperty = stringValue, IntProperty = intValue };\n            schema.Default = new StringAndIntClass() { StringProperty = \"a different string value\", IntProperty = 7 };\n\n            JToken result = SchemaDataGenerator.GenerateData(schema);\n\n            Assert.NotNull(result);\n            Assert.NotNull(result[\"StringProperty\"]);\n            Assert.Equal(stringValue, result[\"StringProperty\"].Value<string>());\n            Assert.NotNull(result[\"IntProperty\"]);\n            Assert.Equal(intValue, result[\"IntProperty\"].Value<int>());\n        }\n\n        [Fact]\n        public void GenerateData_WithStringNoFormat_ReturnsEmptyString()\n        {\n            OpenApiSchema schema = new OpenApiSchema();\n            schema.Type = \"string\";\n            schema.Format = null;\n\n            JToken result = SchemaDataGenerator.GenerateData(schema);\n\n            Assert.NotNull(result);\n            Assert.True(result is JValue);\n            JValue jValue = (JValue)result;\n            Assert.Equal(string.Empty, jValue.Value);\n        }\n\n        [Fact]\n        public void GenerateData_WithStringDateTimeFormat_ReturnsDateTimeString()\n        {\n            OpenApiSchema schema = new OpenApiSchema();\n            schema.Type = \"string\";\n            schema.Format = \"date-time\";\n            // Format we are looking for is ISO8601 - YYYY-MM-DDTHH:MM:SS.MMMMMMM-HH:MM\n            string iso8601RegEx = \"^([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\\\.[0-9]+)(Z|([+-](2[0-3]|[01][0-9]):([0-5][0-9])))$\";\n\n            JToken result = SchemaDataGenerator.GenerateData(schema);\n\n            Assert.NotNull(result);\n            Assert.True(result is JValue);\n            JValue jValue = (JValue)result;\n            string stringValue = jValue.Value<string>();\n            Assert.Matches(iso8601RegEx, stringValue);\n        }\n\n        [Fact]\n        public void GenerateData_WithObjectWithReadOnlyProperty_DoesNotIncludeReadOnlyProperty()\n        {\n            OpenApiSchema rootSchema = new OpenApiSchema()\n            {\n                Type = \"object\",\n                Properties = new Dictionary<string, OpenApiSchema>()\n            };\n            OpenApiSchema readOnlySchema = new OpenApiSchema()\n            {\n                Type = \"integer\",\n                ReadOnly = true\n            };\n            OpenApiSchema writeableSchema = new OpenApiSchema()\n            {\n                Type = \"string\"\n            };\n            rootSchema.Properties.Add(\"Writeable\", writeableSchema);\n            rootSchema.Properties.Add(\"ReadOnly\", readOnlySchema);\n\n            JToken result = SchemaDataGenerator.GenerateData(rootSchema);\n\n            Assert.NotNull(result);\n            Assert.True(result is JObject);\n            JObject jObject = (JObject)result;\n            IEnumerable<string> propertyNames = jObject.Properties().Select(j => j.Name);\n            Assert.Contains(\"Writeable\", propertyNames, StringComparer.Ordinal);\n            Assert.DoesNotContain(\"ReadOnly\", propertyNames, StringComparer.Ordinal);\n        }\n\n        private class StringAndIntClass : IOpenApiAny\n        {\n            public AnyType AnyType => AnyType.Object;\n            public string StringProperty { get; set; }\n            public int IntProperty { get; set; }\n\n            public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)\n            {\n                // Nothing to do here\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Preferences/OpenApiSearchPathsProviderTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Preferences\n{\n    public class OpenApiSearchPathsProviderTests\n    {\n        [Fact]\n        public void WithNoOverrides_ReturnsDefault()\n        {\n            // Arrange\n            NullPreferences preferences = new();\n            OpenApiSearchPathsProvider provider = new(preferences);\n            IEnumerable<string> expectedPaths = OpenApiSearchPathsProvider.DefaultSearchPaths;\n\n            // Act\n            IEnumerable<string> paths = provider.GetOpenApiSearchPaths();\n\n            // Assert\n            AssertPathLists(expectedPaths, paths);\n        }\n\n        [Fact]\n        public void WithFullOverride_ReturnsConfiguredOverride()\n        {\n            // Arrange\n            string searchPathOverrides = \"/red|/green|/blue\";\n            FakePreferences preferences = new();\n            preferences.SetValue(WellKnownPreference.SwaggerSearchPaths, searchPathOverrides);\n            OpenApiSearchPathsProvider provider = new(preferences);\n            string[] expectedPaths = searchPathOverrides.Split('|');\n\n            // Act\n            IEnumerable<string> paths = provider.GetOpenApiSearchPaths();\n\n            // Assert\n            AssertPathLists(expectedPaths, paths);\n        }\n\n        [Fact]\n        public void WithAdditions_ReturnsDefaultPlusAdditions()\n        {\n            // Arrange\n            string[] searchPathAdditions = new[] { \"/red\", \"/green\", \"/blue\" };\n            FakePreferences preferences = new();\n            preferences.SetValue(WellKnownPreference.SwaggerAddToSearchPaths, string.Join('|', searchPathAdditions));\n            OpenApiSearchPathsProvider provider = new(preferences);\n            IEnumerable<string> expectedPaths = OpenApiSearchPathsProvider.DefaultSearchPaths.Union(searchPathAdditions);\n\n            // Act\n            IEnumerable<string> paths = provider.GetOpenApiSearchPaths();\n\n            // Assert\n            AssertPathLists(expectedPaths, paths);\n        }\n\n        [Fact]\n        public void WithRemovals_ReturnsDefaultMinusRemovals()\n        {\n            // Arrange\n            string[] searchPathRemovals = new[] { \"swagger.json\", \"/swagger.json\", \"swagger/v1/swagger.json\", \"/swagger/v1/swagger.json\" };\n            FakePreferences preferences = new();\n            preferences.SetValue(WellKnownPreference.SwaggerRemoveFromSearchPaths, string.Join('|', searchPathRemovals));\n            OpenApiSearchPathsProvider provider = new(preferences);\n            IEnumerable<string> expectedPaths = OpenApiSearchPathsProvider.DefaultSearchPaths.Except(searchPathRemovals);\n\n            // Act\n            IEnumerable<string> paths = provider.GetOpenApiSearchPaths();\n\n            // Assert\n            AssertPathLists(expectedPaths, paths);\n        }\n\n        [Fact]\n        public void WithAdditionsAndRemovals_ReturnsCorrectSet()\n        {\n            // Arrange\n            string[] searchPathAdditions = new[] { \"/red\", \"/green\", \"/blue\" };\n            string[] searchPathRemovals = new[] { \"swagger.json\", \"/swagger.json\", \"swagger/v1/swagger.json\", \"/swagger/v1/swagger.json\" };\n            FakePreferences preferences = new();\n            preferences.SetValue(WellKnownPreference.SwaggerAddToSearchPaths, string.Join('|', searchPathAdditions));\n            preferences.SetValue(WellKnownPreference.SwaggerRemoveFromSearchPaths, string.Join('|', searchPathRemovals));\n            OpenApiSearchPathsProvider provider = new(preferences);\n            IEnumerable<string> expectedPaths = OpenApiSearchPathsProvider.DefaultSearchPaths.Union(searchPathAdditions).Except(searchPathRemovals);\n\n            // Act\n            IEnumerable<string> paths = provider.GetOpenApiSearchPaths();\n\n            // Assert\n            AssertPathLists(expectedPaths, paths);\n        }\n\n        private static void AssertPathLists(IEnumerable<string> expectedPaths, IEnumerable<string> paths)\n        {\n            Assert.NotNull(expectedPaths);\n            Assert.NotNull(paths);\n\n            IEnumerator<string> expectedPathsEnumerator = expectedPaths.GetEnumerator();\n            IEnumerator<string> pathsEnumerator = paths.GetEnumerator();\n\n            while (expectedPathsEnumerator.MoveNext())\n            {\n                Assert.True(pathsEnumerator.MoveNext(), $\"Missing path \\\"{expectedPathsEnumerator.Current}\\\"\");\n                Assert.Equal(expectedPathsEnumerator.Current, pathsEnumerator.Current, StringComparer.Ordinal);\n            }\n\n            if (pathsEnumerator.MoveNext())\n            {\n                // We can't do a one-liner here like the Missing path version above because\n                // the order the second parameter is evaluated regardless of the result of the\n                // evaluation of the first parameter.\n                Assert.Fail($\"Extra path \\\"{pathsEnumerator.Current}\\\"\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Preferences/TestDefaultPreferences.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.txt file in the project root for more information.\n\nusing System.Collections.Generic;\n\nnamespace Microsoft.HttpRepl.Tests.Preferences\n{\n    internal static class TestDefaultPreferences\n    {\n        internal static Dictionary<string, string> GetDefaultPreferences()\n        {\n            // For now, we'll just use the same defaults as used by the app.\n            return Program.CreateDefaultPreferences();\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Preferences/UserFolderPreferencesTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.UserProfile;\nusing Microsoft.Repl.ConsoleHandling;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Preferences\n{\n    public class UserFolderPreferencesTests\n    {\n        [Fact]\n        public void ReadPreferences_NoPreferencesFile_AllDefaults()\n        {\n            SetupPreferences(out UserFolderPreferences preferences, out _);\n\n            ConfirmAllPreferencesAreDefaults(preferences);\n        }\n\n        [Fact]\n        public void ReadPreferences_BlankPreferencesFile_AllDefaults()\n        {\n            SetupPreferences(out UserFolderPreferences preferences, out MockedFileSystem fileSystem);\n            fileSystem.AddFile(preferences.PreferencesFilePath, \"\");\n\n            ConfirmAllPreferencesAreDefaults(preferences);\n        }\n\n        [Fact]\n        public void ReadPreferences_InvalidPreferencesFile_AllDefaults()\n        {\n            SetupPreferences(out UserFolderPreferences preferences, out MockedFileSystem fileSystem);\n            fileSystem.AddFile(preferences.PreferencesFilePath, \"This is not a valid preferences file.\");\n\n            ConfirmAllPreferencesAreDefaults(preferences);\n        }\n\n        [Fact]\n        public void ReadPreferences_PartiallyInvalidPreferencesFile_ValidPrefsAreSet()\n        {\n            SetupPreferences(out UserFolderPreferences preferences, out MockedFileSystem fileSystem);\n            string settingName = WellKnownPreference.DefaultEditorCommand;\n            string expectedValue = \"Code.exe\";\n            string prefsFileContent = $@\"This first line is invalid for a prefs file.\n{settingName}={expectedValue}\nThis third line is invalid as well\";\n            fileSystem.AddFile(preferences.PreferencesFilePath, prefsFileContent);\n\n            Assert.Equal(expectedValue, preferences.CurrentPreferences[settingName]);\n        }\n\n        [Fact]\n        public void WritePreferences_SomeDefault_OnlyWritesNonDefaultValues()\n        {\n            string defaultEditor = \"Code.exe\";\n            string errorColor = \"BoldMagenta\";\n            string expected = $@\"{WellKnownPreference.ErrorColor}={errorColor}\n{WellKnownPreference.DefaultEditorCommand}={defaultEditor}\";\n\n            SetupPreferences(out UserFolderPreferences preferences, out MockedFileSystem fileSystem);\n\n            // Add one and change one\n            // Only the changes should be written, not any of the defaults.\n            bool succeeded = preferences.SetValue(WellKnownPreference.DefaultEditorCommand, defaultEditor);\n\n            Assert.True(succeeded);\n\n            succeeded = preferences.SetValue(WellKnownPreference.ErrorColor, errorColor);\n\n            Assert.True(succeeded);\n            Assert.Equal(expected, fileSystem.ReadFile(preferences.PreferencesFilePath));\n        }\n\n        [Fact]\n        public void WritePreferences_ChangeNonDefaultToDefault_RemovesDefaultValue()\n        {\n            string originalValue = \"BoldMagenta\";\n            string defaultValue = \"Red\";\n            IDictionary<string, string> defaultPreferences = new Dictionary<string, string> { { WellKnownPreference.ProtocolColor, defaultValue } };\n\n            MockedFileSystem fileSystem = new MockedFileSystem();\n            IUserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            UserFolderPreferences preferences = new UserFolderPreferences(fileSystem, userProfileDirectoryProvider, defaultPreferences);\n\n            // Create a file with a non-default value, read it from the file system and\n            // validate that it was read correctly\n            fileSystem.AddFile(preferences.PreferencesFilePath, $\"{WellKnownPreference.ProtocolColor}={originalValue}\");\n\n            Assert.Equal(originalValue, preferences.CurrentPreferences[WellKnownPreference.ProtocolColor]);\n\n            // Now change it to the default value, write it back to the file system and\n            // validate that it was removed from the file\n            bool succeeded = preferences.SetValue(WellKnownPreference.ProtocolColor, defaultPreferences[WellKnownPreference.ProtocolColor]);\n\n            Assert.True(succeeded);\n            Assert.Equal(string.Empty, fileSystem.ReadFile(preferences.PreferencesFilePath));\n        }\n\n        [Fact]\n        public void SetValue_NoValueNoDefault_PreferenceIsRemoved()\n        {\n            string initialValue = \"BoldRed\";\n            SetupPreferencesWithFileContent($\"{WellKnownPreference.JsonBraceColor}={initialValue}\", out UserFolderPreferences preferences);\n\n            Assert.Equal(\"BoldRed\", preferences.GetValue(WellKnownPreference.JsonBraceColor));\n\n            // JsonBraceColor has no default, so this should remove the preference\n            preferences.SetValue(WellKnownPreference.JsonBraceColor, \"\");\n\n            bool found = preferences.TryGetValue(WellKnownPreference.JsonBraceColor, out _);\n\n            Assert.False(found);\n        }\n\n        [Theory]\n        [MemberData(nameof(GetStringValuesTestData))]\n        public void GetValue_CorrectOutput(string expected, string fileContent, string preferenceName, string defaultValue)\n        {\n            SetupPreferencesWithFileContent(fileContent, out UserFolderPreferences preferences);\n\n            string result = preferences.GetValue(preferenceName, defaultValue);\n\n            Assert.Equal(expected, result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Theory]\n        [MemberData(nameof(GetColorValuesTestData))]\n        public void GetColorValue_CorrectOutput(AllowedColors expected, string fileContent, string preferenceName, AllowedColors defaultValue)\n        {\n            SetupPreferencesWithFileContent(fileContent, out UserFolderPreferences preferences);\n\n            AllowedColors result = preferences.GetColorValue(preferenceName, defaultValue);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Theory]\n        [MemberData(nameof(GetIntValuesTestData))]\n        public void GetIntValue_CorrectOutput(int expected, string fileContent, string preferenceName, int defaultValue)\n        {\n            SetupPreferencesWithFileContent(fileContent, out UserFolderPreferences preferences);\n\n            int result = preferences.GetIntValue(preferenceName, defaultValue);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Theory]\n        [MemberData(nameof(GetBoolValuesTestData))]\n        public void GetBoolValue_CorrectOutput(bool expected, string fileContent, string preferenceName, bool defaultValue)\n        {\n            SetupPreferencesWithFileContent(fileContent, out UserFolderPreferences preferences);\n\n            bool result = preferences.GetBoolValue(preferenceName, defaultValue);\n\n            Assert.Equal(expected, result);\n        }\n\n        public static IEnumerable<object[]> GetStringValuesTestData()\n        {\n            // Empty/blank preferences file falls back to the passed in default.\n            yield return new object[] { \"code.exe\", string.Empty, WellKnownPreference.DefaultEditorCommand, \"code.exe\" };\n            // Actual value is returned\n            yield return new object[] { \"code.exe\", $\"{WellKnownPreference.DefaultEditorCommand}=code.exe\", WellKnownPreference.DefaultEditorCommand, \"notepad.exe\" };\n        }\n\n        public static IEnumerable<object[]> GetColorValuesTestData()\n        {\n            // Empty/blank preferences file falls back to the passed in default\n            yield return new object[] { AllowedColors.Magenta, string.Empty, WellKnownPreference.ErrorColor, AllowedColors.Magenta };\n            // Preference value that isn't an actual color falls back to the passed in default\n            yield return new object[] { AllowedColors.Magenta, $\"{WellKnownPreference.ErrorColor}=ThisIsGibberish\", WellKnownPreference.ErrorColor, AllowedColors.Magenta };\n            // Actual value is returned\n            yield return new object[] { AllowedColors.BoldRed, $\"{WellKnownPreference.ErrorColor}=BoldRed\", WellKnownPreference.ErrorColor, AllowedColors.Cyan };\n        }\n\n        public static IEnumerable<object[]> GetIntValuesTestData()\n        {\n            // Empty/blank preferences file falls back to the passed in default\n            yield return new object[] { 5, string.Empty, WellKnownPreference.JsonIndentSize, 5 };\n            // Preference value that isn't an int falls back to the passed in default\n            yield return new object[] { 5, $\"{WellKnownPreference.JsonIndentSize}=ThisIsGibberish\", WellKnownPreference.JsonIndentSize, 5 };\n            // Actual value is returned\n            yield return new object[] { 5, $\"{WellKnownPreference.JsonIndentSize}=5\", WellKnownPreference.JsonIndentSize, 42 };\n        }\n\n        public static IEnumerable<object[]> GetBoolValuesTestData()\n        {\n            // Empty/blank preferences file falls back to the passed in default\n            yield return new object[] { false, string.Empty, WellKnownPreference.UseDefaultCredentials, false };\n            // Preference value that isn't a bool falls back to the passed in default\n            yield return new object[] { false, $\"{WellKnownPreference.UseDefaultCredentials}=ThisIsGibberish\", WellKnownPreference.UseDefaultCredentials, false };\n            // Actual value is returned\n            yield return new object[] { true, $\"{WellKnownPreference.UseDefaultCredentials}=true\", WellKnownPreference.UseDefaultCredentials, false };\n        }\n\n        private void SetupPreferences(out UserFolderPreferences preferences, out MockedFileSystem fileSystem)\n        {\n            fileSystem = new MockedFileSystem();\n            IUserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            preferences = new UserFolderPreferences(fileSystem, userProfileDirectoryProvider, TestDefaultPreferences.GetDefaultPreferences());\n        }\n\n        private void SetupPreferencesWithFileContent(string fileContent, out UserFolderPreferences preferences)\n        {\n            SetupPreferences(out preferences, out MockedFileSystem fileSystem);\n\n            fileSystem.AddFile(preferences.PreferencesFilePath, fileContent);\n        }\n\n        private void ConfirmAllPreferencesAreDefaults(IPreferences preferences)\n        {\n            var defaultPreferences = TestDefaultPreferences.GetDefaultPreferences();\n            var currentPreferences = preferences.CurrentPreferences;\n            Assert.Equal(defaultPreferences.Count, currentPreferences.Count);\n            foreach (KeyValuePair<string, string> kvp in defaultPreferences)\n            {\n                Assert.True(currentPreferences.ContainsKey(kvp.Key));\n                Assert.Equal(kvp.Value, currentPreferences[kvp.Key]);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Resources/OpenApiDescriptions/MicrosoftGraph.PowershellSdk.Analytics.json",
    "content": "{\n  \"openapi\": \"3.0.1\",\n  \"info\": {\n    \"title\": \"Analytics\",\n    \"version\": \"v1.0\"\n  },\n  \"servers\": [\n    {\n      \"url\": \"https://graph.microsoft.com/v1.0/\",\n      \"description\": \"Core\"\n    }\n  ],\n  \"paths\": {\n    \"/users/{user-id}/insights\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get insights from users\",\n        \"operationId\": \"users_GetInsights\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"trending\",\n                  \"shared\",\n                  \"used\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"trending\",\n                  \"shared\",\n                  \"used\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.officeGraphInsights\"\n                }\n              }\n            },\n            \"links\": {\n              \"trending\": {\n                \"operationId\": \"user.insights.GetTrending\",\n                \"parameters\": {\n                  \"user-id\": \"$request.path.user-id\",\n                  \"trending-id\": \"$response.body#/id\"\n                }\n              },\n              \"shared\": {\n                \"operationId\": \"user.insights.GetShared\",\n                \"parameters\": {\n                  \"user-id\": \"$request.path.user-id\",\n                  \"sharedInsight-id\": \"$response.body#/id\"\n                }\n              },\n              \"used\": {\n                \"operationId\": \"user.insights.GetUsed\",\n                \"parameters\": {\n                  \"user-id\": \"$request.path.user-id\",\n                  \"usedInsight-id\": \"$response.body#/id\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      },\n      \"patch\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Update the navigation property insights in users\",\n        \"operationId\": \"users_UpdateInsights\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.officeGraphInsights\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/users/{user-id}/insights/shared\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get shared from users\",\n        \"operationId\": \"users.insights_ListShared\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/top\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/skip\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/search\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/filter\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/count\"\n          },\n          {\n            \"name\": \"$orderby\",\n            \"in\": \"query\",\n            \"description\": \"Order items by property values\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"id desc\",\n                  \"lastShared\",\n                  \"lastShared desc\",\n                  \"sharingHistory\",\n                  \"sharingHistory desc\",\n                  \"resourceVisualization\",\n                  \"resourceVisualization desc\",\n                  \"resourceReference\",\n                  \"resourceReference desc\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"lastShared\",\n                  \"sharingHistory\",\n                  \"resourceVisualization\",\n                  \"resourceReference\",\n                  \"lastSharedMethod\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"lastSharedMethod\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"title\": \"Collection of sharedInsight\",\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"value\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"$ref\": \"#/components/schemas/microsoft.graph.sharedInsight\"\n                      }\n                    },\n                    \"@odata.nextLink\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-pageable\": {\n          \"nextLinkName\": \"@odata.nextLink\",\n          \"operationName\": \"listMore\"\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"post\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Create new navigation property to shared for users\",\n        \"operationId\": \"users.insights_CreateShared\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.sharedInsight\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created navigation property.\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.sharedInsight\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/users/{user-id}/insights/shared/{sharedInsight-id}\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get shared from users\",\n        \"operationId\": \"users.insights_GetShared\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"sharedInsight-id\",\n            \"in\": \"path\",\n            \"description\": \"key: sharedInsight-id of sharedInsight\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"sharedInsight\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"lastShared\",\n                  \"sharingHistory\",\n                  \"resourceVisualization\",\n                  \"resourceReference\",\n                  \"lastSharedMethod\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"lastSharedMethod\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.sharedInsight\"\n                }\n              }\n            },\n            \"links\": {\n              \"lastSharedMethod\": {\n                \"operationId\": \"officeGraphInsights.shared.GetLastSharedMethod\",\n                \"parameters\": {\n                  \"user-id\": \"$request.path.user-id\",\n                  \"sharedInsight-id\": \"$request.path.sharedInsight-id\",\n                  \"entity-id\": \"$response.body#/id\"\n                }\n              },\n              \"resource\": {\n                \"operationId\": \"officeGraphInsights.shared.GetResource\",\n                \"parameters\": {\n                  \"user-id\": \"$request.path.user-id\",\n                  \"sharedInsight-id\": \"$request.path.sharedInsight-id\",\n                  \"entity-id\": \"$response.body#/id\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      },\n      \"patch\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Update the navigation property shared in users\",\n        \"operationId\": \"users.insights_UpdateShared\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"sharedInsight-id\",\n            \"in\": \"path\",\n            \"description\": \"key: sharedInsight-id of sharedInsight\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"sharedInsight\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.sharedInsight\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/users/{user-id}/insights/shared/{sharedInsight-id}/lastSharedMethod\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get lastSharedMethod from users\",\n        \"operationId\": \"users.insights.shared_GetLastSharedMethod\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"sharedInsight-id\",\n            \"in\": \"path\",\n            \"description\": \"key: sharedInsight-id of sharedInsight\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"sharedInsight\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      }\n    },\n    \"/users/{user-id}/insights/shared/{sharedInsight-id}/resource\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get resource from users\",\n        \"operationId\": \"users.insights.shared_GetResource\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"sharedInsight-id\",\n            \"in\": \"path\",\n            \"description\": \"key: sharedInsight-id of sharedInsight\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"sharedInsight\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      }\n    },\n    \"/users/{user-id}/insights/trending\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get trending from users\",\n        \"operationId\": \"users.insights_ListTrending\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/top\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/skip\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/search\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/filter\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/count\"\n          },\n          {\n            \"name\": \"$orderby\",\n            \"in\": \"query\",\n            \"description\": \"Order items by property values\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"id desc\",\n                  \"weight\",\n                  \"weight desc\",\n                  \"resourceVisualization\",\n                  \"resourceVisualization desc\",\n                  \"resourceReference\",\n                  \"resourceReference desc\",\n                  \"lastModifiedDateTime\",\n                  \"lastModifiedDateTime desc\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"weight\",\n                  \"resourceVisualization\",\n                  \"resourceReference\",\n                  \"lastModifiedDateTime\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"title\": \"Collection of trending\",\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"value\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"$ref\": \"#/components/schemas/microsoft.graph.trending\"\n                      }\n                    },\n                    \"@odata.nextLink\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-pageable\": {\n          \"nextLinkName\": \"@odata.nextLink\",\n          \"operationName\": \"listMore\"\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"post\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Create new navigation property to trending for users\",\n        \"operationId\": \"users.insights_CreateTrending\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.trending\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created navigation property.\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.trending\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/users/{user-id}/insights/trending/{trending-id}\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get trending from users\",\n        \"operationId\": \"users.insights_GetTrending\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"trending-id\",\n            \"in\": \"path\",\n            \"description\": \"key: trending-id of trending\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"trending\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"weight\",\n                  \"resourceVisualization\",\n                  \"resourceReference\",\n                  \"lastModifiedDateTime\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.trending\"\n                }\n              }\n            },\n            \"links\": {\n              \"resource\": {\n                \"operationId\": \"officeGraphInsights.trending.GetResource\",\n                \"parameters\": {\n                  \"user-id\": \"$request.path.user-id\",\n                  \"trending-id\": \"$request.path.trending-id\",\n                  \"entity-id\": \"$response.body#/id\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      },\n      \"patch\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Update the navigation property trending in users\",\n        \"operationId\": \"users.insights_UpdateTrending\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"trending-id\",\n            \"in\": \"path\",\n            \"description\": \"key: trending-id of trending\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"trending\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.trending\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/users/{user-id}/insights/trending/{trending-id}/resource\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get resource from users\",\n        \"operationId\": \"users.insights.trending_GetResource\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"trending-id\",\n            \"in\": \"path\",\n            \"description\": \"key: trending-id of trending\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"trending\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      }\n    },\n    \"/users/{user-id}/insights/used\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get used from users\",\n        \"operationId\": \"users.insights_ListUsed\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/top\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/skip\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/search\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/filter\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/count\"\n          },\n          {\n            \"name\": \"$orderby\",\n            \"in\": \"query\",\n            \"description\": \"Order items by property values\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"id desc\",\n                  \"lastUsed\",\n                  \"lastUsed desc\",\n                  \"resourceVisualization\",\n                  \"resourceVisualization desc\",\n                  \"resourceReference\",\n                  \"resourceReference desc\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"lastUsed\",\n                  \"resourceVisualization\",\n                  \"resourceReference\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"title\": \"Collection of usedInsight\",\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"value\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"$ref\": \"#/components/schemas/microsoft.graph.usedInsight\"\n                      }\n                    },\n                    \"@odata.nextLink\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-pageable\": {\n          \"nextLinkName\": \"@odata.nextLink\",\n          \"operationName\": \"listMore\"\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"post\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Create new navigation property to used for users\",\n        \"operationId\": \"users.insights_CreateUsed\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.usedInsight\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created navigation property.\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.usedInsight\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/users/{user-id}/insights/used/{usedInsight-id}\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get used from users\",\n        \"operationId\": \"users.insights_GetUsed\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"usedInsight-id\",\n            \"in\": \"path\",\n            \"description\": \"key: usedInsight-id of usedInsight\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"usedInsight\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"lastUsed\",\n                  \"resourceVisualization\",\n                  \"resourceReference\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"resource\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.usedInsight\"\n                }\n              }\n            },\n            \"links\": {\n              \"resource\": {\n                \"operationId\": \"officeGraphInsights.used.GetResource\",\n                \"parameters\": {\n                  \"user-id\": \"$request.path.user-id\",\n                  \"usedInsight-id\": \"$request.path.usedInsight-id\",\n                  \"entity-id\": \"$response.body#/id\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      },\n      \"patch\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Update the navigation property used in users\",\n        \"operationId\": \"users.insights_UpdateUsed\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"usedInsight-id\",\n            \"in\": \"path\",\n            \"description\": \"key: usedInsight-id of usedInsight\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"usedInsight\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.usedInsight\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/users/{user-id}/insights/used/{usedInsight-id}/resource\": {\n      \"get\": {\n        \"tags\": [\n          \"users.officeGraphInsights\"\n        ],\n        \"summary\": \"Get resource from users\",\n        \"operationId\": \"users.insights.used_GetResource\",\n        \"parameters\": [\n          {\n            \"name\": \"user-id\",\n            \"in\": \"path\",\n            \"description\": \"key: user-id of user\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"user\"\n          },\n          {\n            \"name\": \"usedInsight-id\",\n            \"in\": \"path\",\n            \"description\": \"key: usedInsight-id of usedInsight\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"usedInsight\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      }\n    }\n  },\n  \"components\": {\n    \"schemas\": {\n      \"microsoft.graph.officeGraphInsights\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"officeGraphInsights\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"trending\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.trending\"\n                },\n                \"description\": \"Calculated relationship identifying documents trending around a user. Trending documents are calculated based on activity of the user's closest network of people and include files stored in OneDrive for Business and SharePoint. Trending insights help the user to discover potentially useful content that the user has access to, but has never viewed before.\"\n              },\n              \"shared\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.sharedInsight\"\n                },\n                \"description\": \"Calculated relationship identifying documents shared with or by the user. This includes URLs, file attachments, and reference attachments to OneDrive for Business and SharePoint files found in Outlook messages and meetings. This also includes URLs and reference attachments to Teams conversations. Ordered by recency of share.\"\n              },\n              \"used\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.usedInsight\"\n                },\n                \"description\": \"Calculated relationship identifying the latest documents viewed or modified by a user, including OneDrive for Business and SharePoint documents, ranked by recency of use.\"\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"trending\": [\n            {\n              \"@odata.type\": \"microsoft.graph.trending\"\n            }\n          ],\n          \"shared\": [\n            {\n              \"@odata.type\": \"microsoft.graph.sharedInsight\"\n            }\n          ],\n          \"used\": [\n            {\n              \"@odata.type\": \"microsoft.graph.usedInsight\"\n            }\n          ]\n        }\n      },\n      \"microsoft.graph.sharedInsight\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"sharedInsight\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"lastShared\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.sharingDetail\"\n              },\n              \"sharingHistory\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.sharingDetail\"\n                }\n              },\n              \"resourceVisualization\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.resourceVisualization\"\n              },\n              \"resourceReference\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.resourceReference\"\n              },\n              \"lastSharedMethod\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n              },\n              \"resource\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"lastShared\": {\n            \"@odata.type\": \"microsoft.graph.sharingDetail\"\n          },\n          \"sharingHistory\": [\n            {\n              \"@odata.type\": \"microsoft.graph.sharingDetail\"\n            }\n          ],\n          \"resourceVisualization\": {\n            \"@odata.type\": \"microsoft.graph.resourceVisualization\"\n          },\n          \"resourceReference\": {\n            \"@odata.type\": \"microsoft.graph.resourceReference\"\n          },\n          \"lastSharedMethod\": {\n            \"@odata.type\": \"microsoft.graph.entity\"\n          },\n          \"resource\": {\n            \"@odata.type\": \"microsoft.graph.entity\"\n          }\n        }\n      },\n      \"microsoft.graph.entity\": {\n        \"title\": \"entity\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"id\": {\n            \"type\": \"string\",\n            \"description\": \"Read-only.\"\n          }\n        },\n        \"example\": {\n          \"id\": \"string (identifier)\"\n        }\n      },\n      \"microsoft.graph.trending\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"trending\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"weight\": {\n                \"type\": \"number\",\n                \"description\": \"Value indicating how much the document is currently trending. The larger the number, the more the document is currently trending around the user (the more relevant it is). Returned documents are sorted by this value.\",\n                \"format\": \"double\"\n              },\n              \"resourceVisualization\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.resourceVisualization\"\n              },\n              \"resourceReference\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.resourceReference\"\n              },\n              \"lastModifiedDateTime\": {\n                \"pattern\": \"^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$\",\n                \"type\": \"string\",\n                \"format\": \"date-time\",\n                \"nullable\": true\n              },\n              \"resource\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"weight\": \"double\",\n          \"resourceVisualization\": {\n            \"@odata.type\": \"microsoft.graph.resourceVisualization\"\n          },\n          \"resourceReference\": {\n            \"@odata.type\": \"microsoft.graph.resourceReference\"\n          },\n          \"lastModifiedDateTime\": \"string (timestamp)\",\n          \"resource\": {\n            \"@odata.type\": \"microsoft.graph.entity\"\n          }\n        }\n      },\n      \"microsoft.graph.usedInsight\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"usedInsight\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"lastUsed\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.usageDetails\"\n              },\n              \"resourceVisualization\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.resourceVisualization\"\n              },\n              \"resourceReference\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.resourceReference\"\n              },\n              \"resource\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"lastUsed\": {\n            \"@odata.type\": \"microsoft.graph.usageDetails\"\n          },\n          \"resourceVisualization\": {\n            \"@odata.type\": \"microsoft.graph.resourceVisualization\"\n          },\n          \"resourceReference\": {\n            \"@odata.type\": \"microsoft.graph.resourceReference\"\n          },\n          \"resource\": {\n            \"@odata.type\": \"microsoft.graph.entity\"\n          }\n        }\n      },\n      \"microsoft.graph.sharingDetail\": {\n        \"title\": \"sharingDetail\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"sharedBy\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.insightIdentity\"\n          },\n          \"sharedDateTime\": {\n            \"pattern\": \"^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$\",\n            \"type\": \"string\",\n            \"description\": \"The date and time the file was last shared. The timestamp represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 would look like this: 2014-01-01T00:00:00Z. Read-only.\",\n            \"format\": \"date-time\",\n            \"nullable\": true\n          },\n          \"sharingSubject\": {\n            \"type\": \"string\",\n            \"description\": \"The subject with which the document was shared.\",\n            \"nullable\": true\n          },\n          \"sharingType\": {\n            \"type\": \"string\",\n            \"description\": \"Determines the way the document was shared, can be by a 'Link', 'Attachment', 'Group', 'Site'.\",\n            \"nullable\": true\n          },\n          \"sharingReference\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.resourceReference\"\n          }\n        },\n        \"example\": {\n          \"sharedBy\": {\n            \"@odata.type\": \"microsoft.graph.insightIdentity\"\n          },\n          \"sharedDateTime\": \"string (timestamp)\",\n          \"sharingSubject\": \"string\",\n          \"sharingType\": \"string\",\n          \"sharingReference\": {\n            \"@odata.type\": \"microsoft.graph.resourceReference\"\n          }\n        }\n      },\n      \"microsoft.graph.resourceVisualization\": {\n        \"title\": \"resourceVisualization\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"title\": {\n            \"type\": \"string\",\n            \"description\": \"The item's title text.\",\n            \"nullable\": true\n          },\n          \"type\": {\n            \"type\": \"string\",\n            \"description\": \"The item's media type. Can be used for filtering for a specific file based on a specific type. See below for supported types.\",\n            \"nullable\": true\n          },\n          \"mediaType\": {\n            \"type\": \"string\",\n            \"description\": \"The item's media type. Can be used for filtering for a specific type of file based on supported IANA Media Mime Types. Note that not all Media Mime Types are supported.\",\n            \"nullable\": true\n          },\n          \"previewImageUrl\": {\n            \"type\": \"string\",\n            \"description\": \"A URL leading to the preview image for the item.\",\n            \"nullable\": true\n          },\n          \"previewText\": {\n            \"type\": \"string\",\n            \"description\": \"A preview text for the item.\",\n            \"nullable\": true\n          },\n          \"containerWebUrl\": {\n            \"type\": \"string\",\n            \"description\": \"A path leading to the folder in which the item is stored.\",\n            \"nullable\": true\n          },\n          \"containerDisplayName\": {\n            \"type\": \"string\",\n            \"description\": \"A string describing where the item is stored. For example, the name of a SharePoint site or the user name identifying the owner of the OneDrive storing the item.\",\n            \"nullable\": true\n          },\n          \"containerType\": {\n            \"type\": \"string\",\n            \"description\": \"Can be used for filtering by the type of container in which the file is stored. Such as Site or OneDriveBusiness.\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"title\": \"string\",\n          \"type\": \"string\",\n          \"mediaType\": \"string\",\n          \"previewImageUrl\": \"string\",\n          \"previewText\": \"string\",\n          \"containerWebUrl\": \"string\",\n          \"containerDisplayName\": \"string\",\n          \"containerType\": \"string\"\n        }\n      },\n      \"microsoft.graph.resourceReference\": {\n        \"title\": \"resourceReference\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"webUrl\": {\n            \"type\": \"string\",\n            \"description\": \"A URL leading to the referenced item.\",\n            \"nullable\": true\n          },\n          \"id\": {\n            \"type\": \"string\",\n            \"description\": \"The item's unique identifier.\",\n            \"nullable\": true\n          },\n          \"type\": {\n            \"type\": \"string\",\n            \"description\": \"A string value that can be used to classify the item, such as 'microsoft.graph.driveItem'\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"webUrl\": \"string\",\n          \"id\": \"string\",\n          \"type\": \"string\"\n        }\n      },\n      \"microsoft.graph.usageDetails\": {\n        \"title\": \"usageDetails\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"lastAccessedDateTime\": {\n            \"pattern\": \"^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$\",\n            \"type\": \"string\",\n            \"description\": \"The date and time the resource was last accessed by the user. The timestamp represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 would look like this: 2014-01-01T00:00:00Z. Read-only.\",\n            \"format\": \"date-time\",\n            \"nullable\": true\n          },\n          \"lastModifiedDateTime\": {\n            \"pattern\": \"^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$\",\n            \"type\": \"string\",\n            \"description\": \"The date and time the resource was last modified by the user. The timestamp represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 would look like this: 2014-01-01T00:00:00Z. Read-only.\",\n            \"format\": \"date-time\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"lastAccessedDateTime\": \"string (timestamp)\",\n          \"lastModifiedDateTime\": \"string (timestamp)\"\n        }\n      },\n      \"odata.error\": {\n        \"required\": [\n          \"error\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"error\": {\n            \"$ref\": \"#/components/schemas/odata.error.main\"\n          }\n        }\n      },\n      \"microsoft.graph.insightIdentity\": {\n        \"title\": \"insightIdentity\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"displayName\": {\n            \"type\": \"string\",\n            \"description\": \"The display name of the user who shared the item.\",\n            \"nullable\": true\n          },\n          \"id\": {\n            \"type\": \"string\",\n            \"description\": \"The id of the user who shared the item.\",\n            \"nullable\": true\n          },\n          \"address\": {\n            \"type\": \"string\",\n            \"description\": \"The email address of the user who shared the item.\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"displayName\": \"string\",\n          \"id\": \"string\",\n          \"address\": \"string\"\n        }\n      },\n      \"odata.error.main\": {\n        \"required\": [\n          \"code\",\n          \"message\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"code\": {\n            \"type\": \"string\"\n          },\n          \"message\": {\n            \"type\": \"string\"\n          },\n          \"target\": {\n            \"type\": \"string\"\n          },\n          \"details\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"$ref\": \"#/components/schemas/odata.error.detail\"\n            }\n          },\n          \"innererror\": {\n            \"type\": \"object\",\n            \"description\": \"The structure of this object is service-specific\"\n          }\n        }\n      },\n      \"odata.error.detail\": {\n        \"required\": [\n          \"code\",\n          \"message\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"code\": {\n            \"type\": \"string\"\n          },\n          \"message\": {\n            \"type\": \"string\"\n          },\n          \"target\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"responses\": {\n      \"error\": {\n        \"description\": \"error\",\n        \"content\": {\n          \"application/json\": {\n            \"schema\": {\n              \"$ref\": \"#/components/schemas/odata.error\"\n            }\n          }\n        }\n      }\n    },\n    \"parameters\": {\n      \"top\": {\n        \"name\": \"$top\",\n        \"in\": \"query\",\n        \"description\": \"Show only the first n items\",\n        \"schema\": {\n          \"minimum\": 0,\n          \"type\": \"integer\"\n        },\n        \"example\": 50\n      },\n      \"skip\": {\n        \"name\": \"$skip\",\n        \"in\": \"query\",\n        \"description\": \"Skip the first n items\",\n        \"schema\": {\n          \"minimum\": 0,\n          \"type\": \"integer\"\n        }\n      },\n      \"search\": {\n        \"name\": \"$search\",\n        \"in\": \"query\",\n        \"description\": \"Search items by search phrases\",\n        \"schema\": {\n          \"type\": \"string\"\n        }\n      },\n      \"filter\": {\n        \"name\": \"$filter\",\n        \"in\": \"query\",\n        \"description\": \"Filter items by property values\",\n        \"schema\": {\n          \"type\": \"string\"\n        }\n      },\n      \"count\": {\n        \"name\": \"$count\",\n        \"in\": \"query\",\n        \"description\": \"Include count of items\",\n        \"schema\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"securitySchemes\": {\n      \"azureaadv2\": {\n        \"type\": \"oauth2\",\n        \"flows\": {\n          \"authorizationCode\": {\n            \"authorizationUrl\": \"https://login.microsoftonline.com/common/oauth2/v2.0/authorize\",\n            \"tokenUrl\": \"https://login.microsoftonline.com/common/oauth2/v2.0/token\",\n            \"scopes\": {}\n          }\n        }\n      }\n    }\n  },\n  \"security\": [\n    {\n      \"azureaadv2\": []\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Resources/OpenApiDescriptions/MicrosoftGraph.PowershellSdk.Analytics.yml",
    "content": "# Originally from https://github.com/microsoftgraph/msgraph-sdk-powershell/blob/dev/openApiDocs/v1.0/Analytics.yml\n\nopenapi: 3.0.1\ninfo:\n  title: Analytics\n  version: v1.0\nservers:\n  - url: https://graph.microsoft.com/v1.0/\n    description: Core\npaths:\n  '/users/{user-id}/insights':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get insights from users\n      operationId: users_GetInsights\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - trending\n                - shared\n                - used\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - trending\n                - shared\n                - used\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.officeGraphInsights'\n          links:\n            trending:\n              operationId: user.insights.GetTrending\n              parameters:\n                user-id: $request.path.user-id\n                trending-id: $response.body#/id\n            shared:\n              operationId: user.insights.GetShared\n              parameters:\n                user-id: $request.path.user-id\n                sharedInsight-id: $response.body#/id\n            used:\n              operationId: user.insights.GetUsed\n              parameters:\n                user-id: $request.path.user-id\n                usedInsight-id: $response.body#/id\n        default:\n          $ref: '#/components/responses/error'\n    patch:\n      tags:\n        - users.officeGraphInsights\n      summary: Update the navigation property insights in users\n      operationId: users_UpdateInsights\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n      requestBody:\n        description: New navigation property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.officeGraphInsights'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/users/{user-id}/insights/shared':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get shared from users\n      operationId: users.insights_ListShared\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - $ref: '#/components/parameters/top'\n        - $ref: '#/components/parameters/skip'\n        - $ref: '#/components/parameters/search'\n        - $ref: '#/components/parameters/filter'\n        - $ref: '#/components/parameters/count'\n        - name: $orderby\n          in: query\n          description: Order items by property values\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - id desc\n                - lastShared\n                - lastShared desc\n                - sharingHistory\n                - sharingHistory desc\n                - resourceVisualization\n                - resourceVisualization desc\n                - resourceReference\n                - resourceReference desc\n              type: string\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - lastShared\n                - sharingHistory\n                - resourceVisualization\n                - resourceReference\n                - lastSharedMethod\n                - resource\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - lastSharedMethod\n                - resource\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                title: Collection of sharedInsight\n                type: object\n                properties:\n                  value:\n                    type: array\n                    items:\n                      $ref: '#/components/schemas/microsoft.graph.sharedInsight'\n                  '@odata.nextLink':\n                    type: string\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-pageable:\n        nextLinkName: '@odata.nextLink'\n        operationName: listMore\n      x-ms-docs-operation-type: operation\n    post:\n      tags:\n        - users.officeGraphInsights\n      summary: Create new navigation property to shared for users\n      operationId: users.insights_CreateShared\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n      requestBody:\n        description: New navigation property\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.sharedInsight'\n        required: true\n      responses:\n        '201':\n          description: Created navigation property.\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.sharedInsight'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/users/{user-id}/insights/shared/{sharedInsight-id}':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get shared from users\n      operationId: users.insights_GetShared\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: sharedInsight-id\n          in: path\n          description: 'key: sharedInsight-id of sharedInsight'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: sharedInsight\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - lastShared\n                - sharingHistory\n                - resourceVisualization\n                - resourceReference\n                - lastSharedMethod\n                - resource\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - lastSharedMethod\n                - resource\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.sharedInsight'\n          links:\n            lastSharedMethod:\n              operationId: officeGraphInsights.shared.GetLastSharedMethod\n              parameters:\n                user-id: $request.path.user-id\n                sharedInsight-id: $request.path.sharedInsight-id\n                entity-id: $response.body#/id\n            resource:\n              operationId: officeGraphInsights.shared.GetResource\n              parameters:\n                user-id: $request.path.user-id\n                sharedInsight-id: $request.path.sharedInsight-id\n                entity-id: $response.body#/id\n        default:\n          $ref: '#/components/responses/error'\n    patch:\n      tags:\n        - users.officeGraphInsights\n      summary: Update the navigation property shared in users\n      operationId: users.insights_UpdateShared\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: sharedInsight-id\n          in: path\n          description: 'key: sharedInsight-id of sharedInsight'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: sharedInsight\n      requestBody:\n        description: New navigation property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.sharedInsight'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/users/{user-id}/insights/shared/{sharedInsight-id}/lastSharedMethod':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get lastSharedMethod from users\n      operationId: users.insights.shared_GetLastSharedMethod\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: sharedInsight-id\n          in: path\n          description: 'key: sharedInsight-id of sharedInsight'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: sharedInsight\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.entity'\n        default:\n          $ref: '#/components/responses/error'\n  '/users/{user-id}/insights/shared/{sharedInsight-id}/resource':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get resource from users\n      operationId: users.insights.shared_GetResource\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: sharedInsight-id\n          in: path\n          description: 'key: sharedInsight-id of sharedInsight'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: sharedInsight\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.entity'\n        default:\n          $ref: '#/components/responses/error'\n  '/users/{user-id}/insights/trending':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get trending from users\n      operationId: users.insights_ListTrending\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - $ref: '#/components/parameters/top'\n        - $ref: '#/components/parameters/skip'\n        - $ref: '#/components/parameters/search'\n        - $ref: '#/components/parameters/filter'\n        - $ref: '#/components/parameters/count'\n        - name: $orderby\n          in: query\n          description: Order items by property values\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - id desc\n                - weight\n                - weight desc\n                - resourceVisualization\n                - resourceVisualization desc\n                - resourceReference\n                - resourceReference desc\n                - lastModifiedDateTime\n                - lastModifiedDateTime desc\n              type: string\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - weight\n                - resourceVisualization\n                - resourceReference\n                - lastModifiedDateTime\n                - resource\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - resource\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                title: Collection of trending\n                type: object\n                properties:\n                  value:\n                    type: array\n                    items:\n                      $ref: '#/components/schemas/microsoft.graph.trending'\n                  '@odata.nextLink':\n                    type: string\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-pageable:\n        nextLinkName: '@odata.nextLink'\n        operationName: listMore\n      x-ms-docs-operation-type: operation\n    post:\n      tags:\n        - users.officeGraphInsights\n      summary: Create new navigation property to trending for users\n      operationId: users.insights_CreateTrending\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n      requestBody:\n        description: New navigation property\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.trending'\n        required: true\n      responses:\n        '201':\n          description: Created navigation property.\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.trending'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/users/{user-id}/insights/trending/{trending-id}':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get trending from users\n      operationId: users.insights_GetTrending\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: trending-id\n          in: path\n          description: 'key: trending-id of trending'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: trending\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - weight\n                - resourceVisualization\n                - resourceReference\n                - lastModifiedDateTime\n                - resource\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - resource\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.trending'\n          links:\n            resource:\n              operationId: officeGraphInsights.trending.GetResource\n              parameters:\n                user-id: $request.path.user-id\n                trending-id: $request.path.trending-id\n                entity-id: $response.body#/id\n        default:\n          $ref: '#/components/responses/error'\n    patch:\n      tags:\n        - users.officeGraphInsights\n      summary: Update the navigation property trending in users\n      operationId: users.insights_UpdateTrending\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: trending-id\n          in: path\n          description: 'key: trending-id of trending'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: trending\n      requestBody:\n        description: New navigation property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.trending'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/users/{user-id}/insights/trending/{trending-id}/resource':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get resource from users\n      operationId: users.insights.trending_GetResource\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: trending-id\n          in: path\n          description: 'key: trending-id of trending'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: trending\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.entity'\n        default:\n          $ref: '#/components/responses/error'\n  '/users/{user-id}/insights/used':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get used from users\n      operationId: users.insights_ListUsed\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - $ref: '#/components/parameters/top'\n        - $ref: '#/components/parameters/skip'\n        - $ref: '#/components/parameters/search'\n        - $ref: '#/components/parameters/filter'\n        - $ref: '#/components/parameters/count'\n        - name: $orderby\n          in: query\n          description: Order items by property values\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - id desc\n                - lastUsed\n                - lastUsed desc\n                - resourceVisualization\n                - resourceVisualization desc\n                - resourceReference\n                - resourceReference desc\n              type: string\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - lastUsed\n                - resourceVisualization\n                - resourceReference\n                - resource\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - resource\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                title: Collection of usedInsight\n                type: object\n                properties:\n                  value:\n                    type: array\n                    items:\n                      $ref: '#/components/schemas/microsoft.graph.usedInsight'\n                  '@odata.nextLink':\n                    type: string\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-pageable:\n        nextLinkName: '@odata.nextLink'\n        operationName: listMore\n      x-ms-docs-operation-type: operation\n    post:\n      tags:\n        - users.officeGraphInsights\n      summary: Create new navigation property to used for users\n      operationId: users.insights_CreateUsed\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n      requestBody:\n        description: New navigation property\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.usedInsight'\n        required: true\n      responses:\n        '201':\n          description: Created navigation property.\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.usedInsight'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/users/{user-id}/insights/used/{usedInsight-id}':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get used from users\n      operationId: users.insights_GetUsed\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: usedInsight-id\n          in: path\n          description: 'key: usedInsight-id of usedInsight'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: usedInsight\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - lastUsed\n                - resourceVisualization\n                - resourceReference\n                - resource\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - resource\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.usedInsight'\n          links:\n            resource:\n              operationId: officeGraphInsights.used.GetResource\n              parameters:\n                user-id: $request.path.user-id\n                usedInsight-id: $request.path.usedInsight-id\n                entity-id: $response.body#/id\n        default:\n          $ref: '#/components/responses/error'\n    patch:\n      tags:\n        - users.officeGraphInsights\n      summary: Update the navigation property used in users\n      operationId: users.insights_UpdateUsed\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: usedInsight-id\n          in: path\n          description: 'key: usedInsight-id of usedInsight'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: usedInsight\n      requestBody:\n        description: New navigation property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.usedInsight'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/users/{user-id}/insights/used/{usedInsight-id}/resource':\n    get:\n      tags:\n        - users.officeGraphInsights\n      summary: Get resource from users\n      operationId: users.insights.used_GetResource\n      parameters:\n        - name: user-id\n          in: path\n          description: 'key: user-id of user'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: user\n        - name: usedInsight-id\n          in: path\n          description: 'key: usedInsight-id of usedInsight'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: usedInsight\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.entity'\n        default:\n          $ref: '#/components/responses/error'\ncomponents:\n  schemas:\n    microsoft.graph.officeGraphInsights:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: officeGraphInsights\n          type: object\n          properties:\n            trending:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.trending'\n              description: 'Calculated relationship identifying documents trending around a user. Trending documents are calculated based on activity of the user''s closest network of people and include files stored in OneDrive for Business and SharePoint. Trending insights help the user to discover potentially useful content that the user has access to, but has never viewed before.'\n            shared:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.sharedInsight'\n              description: 'Calculated relationship identifying documents shared with or by the user. This includes URLs, file attachments, and reference attachments to OneDrive for Business and SharePoint files found in Outlook messages and meetings. This also includes URLs and reference attachments to Teams conversations. Ordered by recency of share.'\n            used:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.usedInsight'\n              description: 'Calculated relationship identifying the latest documents viewed or modified by a user, including OneDrive for Business and SharePoint documents, ranked by recency of use.'\n      example:\n        id: string (identifier)\n        trending:\n          - '@odata.type': microsoft.graph.trending\n        shared:\n          - '@odata.type': microsoft.graph.sharedInsight\n        used:\n          - '@odata.type': microsoft.graph.usedInsight\n    microsoft.graph.sharedInsight:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: sharedInsight\n          type: object\n          properties:\n            lastShared:\n              $ref: '#/components/schemas/microsoft.graph.sharingDetail'\n            sharingHistory:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.sharingDetail'\n            resourceVisualization:\n              $ref: '#/components/schemas/microsoft.graph.resourceVisualization'\n            resourceReference:\n              $ref: '#/components/schemas/microsoft.graph.resourceReference'\n            lastSharedMethod:\n              $ref: '#/components/schemas/microsoft.graph.entity'\n            resource:\n              $ref: '#/components/schemas/microsoft.graph.entity'\n      example:\n        id: string (identifier)\n        lastShared:\n          '@odata.type': microsoft.graph.sharingDetail\n        sharingHistory:\n          - '@odata.type': microsoft.graph.sharingDetail\n        resourceVisualization:\n          '@odata.type': microsoft.graph.resourceVisualization\n        resourceReference:\n          '@odata.type': microsoft.graph.resourceReference\n        lastSharedMethod:\n          '@odata.type': microsoft.graph.entity\n        resource:\n          '@odata.type': microsoft.graph.entity\n    microsoft.graph.entity:\n      title: entity\n      type: object\n      properties:\n        id:\n          type: string\n          description: Read-only.\n      example:\n        id: string (identifier)\n    microsoft.graph.trending:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: trending\n          type: object\n          properties:\n            weight:\n              type: number\n              description: 'Value indicating how much the document is currently trending. The larger the number, the more the document is currently trending around the user (the more relevant it is). Returned documents are sorted by this value.'\n              format: double\n            resourceVisualization:\n              $ref: '#/components/schemas/microsoft.graph.resourceVisualization'\n            resourceReference:\n              $ref: '#/components/schemas/microsoft.graph.resourceReference'\n            lastModifiedDateTime:\n              pattern: '^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$'\n              type: string\n              format: date-time\n              nullable: true\n            resource:\n              $ref: '#/components/schemas/microsoft.graph.entity'\n      example:\n        id: string (identifier)\n        weight: double\n        resourceVisualization:\n          '@odata.type': microsoft.graph.resourceVisualization\n        resourceReference:\n          '@odata.type': microsoft.graph.resourceReference\n        lastModifiedDateTime: string (timestamp)\n        resource:\n          '@odata.type': microsoft.graph.entity\n    microsoft.graph.usedInsight:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: usedInsight\n          type: object\n          properties:\n            lastUsed:\n              $ref: '#/components/schemas/microsoft.graph.usageDetails'\n            resourceVisualization:\n              $ref: '#/components/schemas/microsoft.graph.resourceVisualization'\n            resourceReference:\n              $ref: '#/components/schemas/microsoft.graph.resourceReference'\n            resource:\n              $ref: '#/components/schemas/microsoft.graph.entity'\n      example:\n        id: string (identifier)\n        lastUsed:\n          '@odata.type': microsoft.graph.usageDetails\n        resourceVisualization:\n          '@odata.type': microsoft.graph.resourceVisualization\n        resourceReference:\n          '@odata.type': microsoft.graph.resourceReference\n        resource:\n          '@odata.type': microsoft.graph.entity\n    microsoft.graph.sharingDetail:\n      title: sharingDetail\n      type: object\n      properties:\n        sharedBy:\n          $ref: '#/components/schemas/microsoft.graph.insightIdentity'\n        sharedDateTime:\n          pattern: '^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$'\n          type: string\n          description: 'The date and time the file was last shared. The timestamp represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 would look like this: 2014-01-01T00:00:00Z. Read-only.'\n          format: date-time\n          nullable: true\n        sharingSubject:\n          type: string\n          description: The subject with which the document was shared.\n          nullable: true\n        sharingType:\n          type: string\n          description: 'Determines the way the document was shared, can be by a ''Link'', ''Attachment'', ''Group'', ''Site''.'\n          nullable: true\n        sharingReference:\n          $ref: '#/components/schemas/microsoft.graph.resourceReference'\n      example:\n        sharedBy:\n          '@odata.type': microsoft.graph.insightIdentity\n        sharedDateTime: string (timestamp)\n        sharingSubject: string\n        sharingType: string\n        sharingReference:\n          '@odata.type': microsoft.graph.resourceReference\n    microsoft.graph.resourceVisualization:\n      title: resourceVisualization\n      type: object\n      properties:\n        title:\n          type: string\n          description: The item's title text.\n          nullable: true\n        type:\n          type: string\n          description: The item's media type. Can be used for filtering for a specific file based on a specific type. See below for supported types.\n          nullable: true\n        mediaType:\n          type: string\n          description: The item's media type. Can be used for filtering for a specific type of file based on supported IANA Media Mime Types. Note that not all Media Mime Types are supported.\n          nullable: true\n        previewImageUrl:\n          type: string\n          description: A URL leading to the preview image for the item.\n          nullable: true\n        previewText:\n          type: string\n          description: A preview text for the item.\n          nullable: true\n        containerWebUrl:\n          type: string\n          description: A path leading to the folder in which the item is stored.\n          nullable: true\n        containerDisplayName:\n          type: string\n          description: 'A string describing where the item is stored. For example, the name of a SharePoint site or the user name identifying the owner of the OneDrive storing the item.'\n          nullable: true\n        containerType:\n          type: string\n          description: Can be used for filtering by the type of container in which the file is stored. Such as Site or OneDriveBusiness.\n          nullable: true\n      example:\n        title: string\n        type: string\n        mediaType: string\n        previewImageUrl: string\n        previewText: string\n        containerWebUrl: string\n        containerDisplayName: string\n        containerType: string\n    microsoft.graph.resourceReference:\n      title: resourceReference\n      type: object\n      properties:\n        webUrl:\n          type: string\n          description: A URL leading to the referenced item.\n          nullable: true\n        id:\n          type: string\n          description: The item's unique identifier.\n          nullable: true\n        type:\n          type: string\n          description: 'A string value that can be used to classify the item, such as ''microsoft.graph.driveItem'''\n          nullable: true\n      example:\n        webUrl: string\n        id: string\n        type: string\n    microsoft.graph.usageDetails:\n      title: usageDetails\n      type: object\n      properties:\n        lastAccessedDateTime:\n          pattern: '^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$'\n          type: string\n          description: 'The date and time the resource was last accessed by the user. The timestamp represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 would look like this: 2014-01-01T00:00:00Z. Read-only.'\n          format: date-time\n          nullable: true\n        lastModifiedDateTime:\n          pattern: '^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$'\n          type: string\n          description: 'The date and time the resource was last modified by the user. The timestamp represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 would look like this: 2014-01-01T00:00:00Z. Read-only.'\n          format: date-time\n          nullable: true\n      example:\n        lastAccessedDateTime: string (timestamp)\n        lastModifiedDateTime: string (timestamp)\n    odata.error:\n      required:\n        - error\n      type: object\n      properties:\n        error:\n          $ref: '#/components/schemas/odata.error.main'\n    microsoft.graph.insightIdentity:\n      title: insightIdentity\n      type: object\n      properties:\n        displayName:\n          type: string\n          description: The display name of the user who shared the item.\n          nullable: true\n        id:\n          type: string\n          description: The id of the user who shared the item.\n          nullable: true\n        address:\n          type: string\n          description: The email address of the user who shared the item.\n          nullable: true\n      example:\n        displayName: string\n        id: string\n        address: string\n    odata.error.main:\n      required:\n        - code\n        - message\n      type: object\n      properties:\n        code:\n          type: string\n        message:\n          type: string\n        target:\n          type: string\n        details:\n          type: array\n          items:\n            $ref: '#/components/schemas/odata.error.detail'\n        innererror:\n          type: object\n          description: The structure of this object is service-specific\n    odata.error.detail:\n      required:\n        - code\n        - message\n      type: object\n      properties:\n        code:\n          type: string\n        message:\n          type: string\n        target:\n          type: string\n  responses:\n    error:\n      description: error\n      content:\n        application/json:\n          schema:\n            $ref: '#/components/schemas/odata.error'\n  parameters:\n    top:\n      name: $top\n      in: query\n      description: Show only the first n items\n      schema:\n        minimum: 0\n        type: integer\n      example: 50\n    skip:\n      name: $skip\n      in: query\n      description: Skip the first n items\n      schema:\n        minimum: 0\n        type: integer\n    search:\n      name: $search\n      in: query\n      description: Search items by search phrases\n      schema:\n        type: string\n    filter:\n      name: $filter\n      in: query\n      description: Filter items by property values\n      schema:\n        type: string\n    count:\n      name: $count\n      in: query\n      description: Include count of items\n      schema:\n        type: boolean\n  securitySchemes:\n    azureaadv2:\n      type: oauth2\n      flows:\n        authorizationCode:\n          authorizationUrl: https://login.microsoftonline.com/common/oauth2/v2.0/authorize\n          tokenUrl: https://login.microsoftonline.com/common/oauth2/v2.0/token\n          scopes: { }\nsecurity:\n  - azureaadv2: [ ]\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Resources/OpenApiDescriptions/MicrosoftGraph.PowershellSdk.CloudCommunications.json",
    "content": "{\n  \"openapi\": \"3.0.1\",\n  \"info\": {\n    \"title\": \"CloudCommunications\",\n    \"version\": \"v1.0\"\n  },\n  \"servers\": [\n    {\n      \"url\": \"https://graph.microsoft.com/v1.0/\",\n      \"description\": \"Core\"\n    }\n  ],\n  \"paths\": {\n    \"/communications\": {\n      \"get\": {\n        \"tags\": [\n          \"communications.cloudCommunications\"\n        ],\n        \"summary\": \"Get communications\",\n        \"operationId\": \"communications.cloudCommunications_GetCloudCommunications\",\n        \"parameters\": [\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"calls\",\n                  \"onlineMeetings\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"calls\",\n                  \"onlineMeetings\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved entity\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.cloudCommunications\"\n                }\n              }\n            },\n            \"links\": {\n              \"calls\": {\n                \"operationId\": \"communications.GetCalls\",\n                \"parameters\": {\n                  \"call-id\": \"$response.body#/id\"\n                }\n              },\n              \"onlineMeetings\": {\n                \"operationId\": \"communications.GetOnlineMeetings\",\n                \"parameters\": {\n                  \"onlineMeeting-id\": \"$response.body#/id\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"patch\": {\n        \"tags\": [\n          \"communications.cloudCommunications\"\n        ],\n        \"summary\": \"Update communications\",\n        \"operationId\": \"communications.cloudCommunications_UpdateCloudCommunications\",\n        \"requestBody\": {\n          \"description\": \"New property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.cloudCommunications\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/communications/calls\": {\n      \"get\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Get calls from communications\",\n        \"operationId\": \"communications_ListCalls\",\n        \"parameters\": [\n          {\n            \"$ref\": \"#/components/parameters/top\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/skip\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/search\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/filter\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/count\"\n          },\n          {\n            \"name\": \"$orderby\",\n            \"in\": \"query\",\n            \"description\": \"Order items by property values\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"id desc\",\n                  \"state\",\n                  \"state desc\",\n                  \"mediaState\",\n                  \"mediaState desc\",\n                  \"resultInfo\",\n                  \"resultInfo desc\",\n                  \"direction\",\n                  \"direction desc\",\n                  \"subject\",\n                  \"subject desc\",\n                  \"callbackUri\",\n                  \"callbackUri desc\",\n                  \"callRoutes\",\n                  \"callRoutes desc\",\n                  \"source\",\n                  \"source desc\",\n                  \"targets\",\n                  \"targets desc\",\n                  \"requestedModalities\",\n                  \"requestedModalities desc\",\n                  \"mediaConfig\",\n                  \"mediaConfig desc\",\n                  \"chatInfo\",\n                  \"chatInfo desc\",\n                  \"callOptions\",\n                  \"callOptions desc\",\n                  \"meetingInfo\",\n                  \"meetingInfo desc\",\n                  \"tenantId\",\n                  \"tenantId desc\",\n                  \"myParticipantId\",\n                  \"myParticipantId desc\",\n                  \"toneInfo\",\n                  \"toneInfo desc\",\n                  \"callChainId\",\n                  \"callChainId desc\",\n                  \"incomingContext\",\n                  \"incomingContext desc\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"state\",\n                  \"mediaState\",\n                  \"resultInfo\",\n                  \"direction\",\n                  \"subject\",\n                  \"callbackUri\",\n                  \"callRoutes\",\n                  \"source\",\n                  \"targets\",\n                  \"requestedModalities\",\n                  \"mediaConfig\",\n                  \"chatInfo\",\n                  \"callOptions\",\n                  \"meetingInfo\",\n                  \"tenantId\",\n                  \"myParticipantId\",\n                  \"toneInfo\",\n                  \"callChainId\",\n                  \"incomingContext\",\n                  \"participants\",\n                  \"operations\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"participants\",\n                  \"operations\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"title\": \"Collection of call\",\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"value\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"$ref\": \"#/components/schemas/microsoft.graph.call\"\n                      }\n                    },\n                    \"@odata.nextLink\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-pageable\": {\n          \"nextLinkName\": \"@odata.nextLink\",\n          \"operationName\": \"listMore\"\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"post\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Create new navigation property to calls for communications\",\n        \"operationId\": \"communications_CreateCalls\",\n        \"requestBody\": {\n          \"description\": \"New navigation property\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.call\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created navigation property.\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.call\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/communications/calls/{call-id}\": {\n      \"get\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Get calls from communications\",\n        \"operationId\": \"communications_GetCalls\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"state\",\n                  \"mediaState\",\n                  \"resultInfo\",\n                  \"direction\",\n                  \"subject\",\n                  \"callbackUri\",\n                  \"callRoutes\",\n                  \"source\",\n                  \"targets\",\n                  \"requestedModalities\",\n                  \"mediaConfig\",\n                  \"chatInfo\",\n                  \"callOptions\",\n                  \"meetingInfo\",\n                  \"tenantId\",\n                  \"myParticipantId\",\n                  \"toneInfo\",\n                  \"callChainId\",\n                  \"incomingContext\",\n                  \"participants\",\n                  \"operations\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\",\n                  \"participants\",\n                  \"operations\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.call\"\n                }\n              }\n            },\n            \"links\": {\n              \"participants\": {\n                \"operationId\": \"cloudCommunications.calls.GetParticipants\",\n                \"parameters\": {\n                  \"call-id\": \"$request.path.call-id\",\n                  \"participant-id\": \"$response.body#/id\"\n                }\n              },\n              \"operations\": {\n                \"operationId\": \"cloudCommunications.calls.GetOperations\",\n                \"parameters\": {\n                  \"call-id\": \"$request.path.call-id\",\n                  \"commsOperation-id\": \"$response.body#/id\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      },\n      \"patch\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Update the navigation property calls in communications\",\n        \"operationId\": \"communications_UpdateCalls\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.call\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.answer\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action answer\",\n        \"operationId\": \"communications.calls_answer\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"callbackUri\": {\n                    \"type\": \"string\"\n                  },\n                  \"mediaConfig\": {\n                    \"$ref\": \"#/components/schemas/microsoft.graph.mediaConfig\"\n                  },\n                  \"acceptedModalities\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"$ref\": \"#/components/schemas/microsoft.graph.modality\"\n                    }\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.changeScreenSharingRole\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action changeScreenSharingRole\",\n        \"operationId\": \"communications.calls_changeScreenSharingRole\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"role\": {\n                    \"$ref\": \"#/components/schemas/microsoft.graph.screenSharingRole\"\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.keepAlive\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action keepAlive\",\n        \"operationId\": \"communications.calls_keepAlive\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.mute\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action mute\",\n        \"operationId\": \"communications.calls_mute\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"clientContext\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Success\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.muteParticipantOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.playPrompt\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action playPrompt\",\n        \"operationId\": \"communications.calls_playPrompt\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"prompts\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"$ref\": \"#/components/schemas/microsoft.graph.prompt\"\n                    }\n                  },\n                  \"clientContext\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Success\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.playPromptOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.recordResponse\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action recordResponse\",\n        \"operationId\": \"communications.calls_recordResponse\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"prompts\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"$ref\": \"#/components/schemas/microsoft.graph.prompt\"\n                    }\n                  },\n                  \"bargeInAllowed\": {\n                    \"type\": \"boolean\",\n                    \"default\": false,\n                    \"nullable\": true\n                  },\n                  \"initialSilenceTimeoutInSeconds\": {\n                    \"maximum\": 2147483647,\n                    \"minimum\": -2147483648,\n                    \"type\": \"integer\",\n                    \"format\": \"int32\",\n                    \"nullable\": true\n                  },\n                  \"maxSilenceTimeoutInSeconds\": {\n                    \"maximum\": 2147483647,\n                    \"minimum\": -2147483648,\n                    \"type\": \"integer\",\n                    \"format\": \"int32\",\n                    \"nullable\": true\n                  },\n                  \"maxRecordDurationInSeconds\": {\n                    \"maximum\": 2147483647,\n                    \"minimum\": -2147483648,\n                    \"type\": \"integer\",\n                    \"format\": \"int32\",\n                    \"nullable\": true\n                  },\n                  \"playBeep\": {\n                    \"type\": \"boolean\",\n                    \"default\": false,\n                    \"nullable\": true\n                  },\n                  \"stopTones\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\",\n                      \"nullable\": true\n                    }\n                  },\n                  \"clientContext\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Success\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.recordOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.redirect\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action redirect\",\n        \"operationId\": \"communications.calls_redirect\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"targets\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"$ref\": \"#/components/schemas/microsoft.graph.invitationParticipantInfo\"\n                    }\n                  },\n                  \"timeout\": {\n                    \"maximum\": 2147483647,\n                    \"minimum\": -2147483648,\n                    \"type\": \"integer\",\n                    \"format\": \"int32\",\n                    \"nullable\": true\n                  },\n                  \"callbackUri\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.reject\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action reject\",\n        \"operationId\": \"communications.calls_reject\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"reason\": {\n                    \"$ref\": \"#/components/schemas/microsoft.graph.rejectReason\"\n                  },\n                  \"callbackUri\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.subscribeToTone\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action subscribeToTone\",\n        \"operationId\": \"communications.calls_subscribeToTone\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"clientContext\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Success\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.subscribeToToneOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.transfer\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action transfer\",\n        \"operationId\": \"communications.calls_transfer\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"transferTarget\": {\n                    \"$ref\": \"#/components/schemas/microsoft.graph.invitationParticipantInfo\"\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.unmute\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action unmute\",\n        \"operationId\": \"communications.calls_unmute\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"clientContext\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Success\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.unmuteParticipantOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/microsoft.graph.updateRecordingStatus\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action updateRecordingStatus\",\n        \"operationId\": \"communications.calls_updateRecordingStatus\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"status\": {\n                    \"$ref\": \"#/components/schemas/microsoft.graph.recordingStatus\"\n                  },\n                  \"clientContext\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Success\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.updateRecordingStatusOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/operations\": {\n      \"get\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Get operations from communications\",\n        \"operationId\": \"communications.calls_ListOperations\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/top\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/skip\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/search\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/filter\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/count\"\n          },\n          {\n            \"name\": \"$orderby\",\n            \"in\": \"query\",\n            \"description\": \"Order items by property values\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"id desc\",\n                  \"status\",\n                  \"status desc\",\n                  \"clientContext\",\n                  \"clientContext desc\",\n                  \"resultInfo\",\n                  \"resultInfo desc\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"status\",\n                  \"clientContext\",\n                  \"resultInfo\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"title\": \"Collection of commsOperation\",\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"value\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n                      }\n                    },\n                    \"@odata.nextLink\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-pageable\": {\n          \"nextLinkName\": \"@odata.nextLink\",\n          \"operationName\": \"listMore\"\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"post\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Create new navigation property to operations for communications\",\n        \"operationId\": \"communications.calls_CreateOperations\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created navigation property.\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/communications/calls/{call-id}/operations/{commsOperation-id}\": {\n      \"get\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Get operations from communications\",\n        \"operationId\": \"communications.calls_GetOperations\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          },\n          {\n            \"name\": \"commsOperation-id\",\n            \"in\": \"path\",\n            \"description\": \"key: commsOperation-id of commsOperation\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"commsOperation\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"status\",\n                  \"clientContext\",\n                  \"resultInfo\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      },\n      \"patch\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Update the navigation property operations in communications\",\n        \"operationId\": \"communications.calls_UpdateOperations\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          },\n          {\n            \"name\": \"commsOperation-id\",\n            \"in\": \"path\",\n            \"description\": \"key: commsOperation-id of commsOperation\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"commsOperation\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/communications/calls/{call-id}/participants\": {\n      \"get\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Get participants from communications\",\n        \"operationId\": \"communications.calls_ListParticipants\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/top\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/skip\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/search\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/filter\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/count\"\n          },\n          {\n            \"name\": \"$orderby\",\n            \"in\": \"query\",\n            \"description\": \"Order items by property values\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"id desc\",\n                  \"info\",\n                  \"info desc\",\n                  \"recordingInfo\",\n                  \"recordingInfo desc\",\n                  \"mediaStreams\",\n                  \"mediaStreams desc\",\n                  \"isMuted\",\n                  \"isMuted desc\",\n                  \"isInLobby\",\n                  \"isInLobby desc\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"info\",\n                  \"recordingInfo\",\n                  \"mediaStreams\",\n                  \"isMuted\",\n                  \"isInLobby\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"title\": \"Collection of participant\",\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"value\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"$ref\": \"#/components/schemas/microsoft.graph.participant\"\n                      }\n                    },\n                    \"@odata.nextLink\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-pageable\": {\n          \"nextLinkName\": \"@odata.nextLink\",\n          \"operationName\": \"listMore\"\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"post\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Create new navigation property to participants for communications\",\n        \"operationId\": \"communications.calls_CreateParticipants\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.participant\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created navigation property.\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.participant\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/communications/calls/{call-id}/participants/{participant-id}\": {\n      \"get\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Get participants from communications\",\n        \"operationId\": \"communications.calls_GetParticipants\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          },\n          {\n            \"name\": \"participant-id\",\n            \"in\": \"path\",\n            \"description\": \"key: participant-id of participant\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"participant\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"info\",\n                  \"recordingInfo\",\n                  \"mediaStreams\",\n                  \"isMuted\",\n                  \"isInLobby\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.participant\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      },\n      \"patch\": {\n        \"tags\": [\n          \"communications.call\"\n        ],\n        \"summary\": \"Update the navigation property participants in communications\",\n        \"operationId\": \"communications.calls_UpdateParticipants\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          },\n          {\n            \"name\": \"participant-id\",\n            \"in\": \"path\",\n            \"description\": \"key: participant-id of participant\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"participant\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.participant\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/communications/calls/{call-id}/participants/{participant-id}/microsoft.graph.mute\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action mute\",\n        \"operationId\": \"communications.calls.participants_mute\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          },\n          {\n            \"name\": \"participant-id\",\n            \"in\": \"path\",\n            \"description\": \"key: participant-id of participant\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"participant\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"clientContext\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Success\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.muteParticipantOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/{call-id}/participants/microsoft.graph.invite\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action invite\",\n        \"operationId\": \"communications.calls.participants_invite\",\n        \"parameters\": [\n          {\n            \"name\": \"call-id\",\n            \"in\": \"path\",\n            \"description\": \"key: call-id of call\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"call\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"participants\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"$ref\": \"#/components/schemas/microsoft.graph.invitationParticipantInfo\"\n                    }\n                  },\n                  \"clientContext\": {\n                    \"type\": \"string\",\n                    \"nullable\": true\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Success\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.inviteParticipantsOperation\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/calls/microsoft.graph.logTeleconferenceDeviceQuality\": {\n      \"post\": {\n        \"tags\": [\n          \"communications.Actions\"\n        ],\n        \"summary\": \"Invoke action logTeleconferenceDeviceQuality\",\n        \"operationId\": \"communications.calls_logTeleconferenceDeviceQuality\",\n        \"requestBody\": {\n          \"description\": \"Action parameters\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"quality\": {\n                    \"$ref\": \"#/components/schemas/microsoft.graph.teleconferenceDeviceQuality\"\n                  }\n                }\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"action\"\n      }\n    },\n    \"/communications/onlineMeetings\": {\n      \"get\": {\n        \"tags\": [\n          \"communications.onlineMeeting\"\n        ],\n        \"summary\": \"Get onlineMeetings from communications\",\n        \"operationId\": \"communications_ListOnlineMeetings\",\n        \"parameters\": [\n          {\n            \"$ref\": \"#/components/parameters/top\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/skip\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/search\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/filter\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/count\"\n          },\n          {\n            \"name\": \"$orderby\",\n            \"in\": \"query\",\n            \"description\": \"Order items by property values\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"id desc\",\n                  \"creationDateTime\",\n                  \"creationDateTime desc\",\n                  \"startDateTime\",\n                  \"startDateTime desc\",\n                  \"endDateTime\",\n                  \"endDateTime desc\",\n                  \"joinWebUrl\",\n                  \"joinWebUrl desc\",\n                  \"subject\",\n                  \"subject desc\",\n                  \"participants\",\n                  \"participants desc\",\n                  \"audioConferencing\",\n                  \"audioConferencing desc\",\n                  \"chatInfo\",\n                  \"chatInfo desc\",\n                  \"videoTeleconferenceId\",\n                  \"videoTeleconferenceId desc\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"creationDateTime\",\n                  \"startDateTime\",\n                  \"endDateTime\",\n                  \"joinWebUrl\",\n                  \"subject\",\n                  \"participants\",\n                  \"audioConferencing\",\n                  \"chatInfo\",\n                  \"videoTeleconferenceId\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"title\": \"Collection of onlineMeeting\",\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"value\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"$ref\": \"#/components/schemas/microsoft.graph.onlineMeeting\"\n                      }\n                    },\n                    \"@odata.nextLink\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-pageable\": {\n          \"nextLinkName\": \"@odata.nextLink\",\n          \"operationName\": \"listMore\"\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"post\": {\n        \"tags\": [\n          \"communications.onlineMeeting\"\n        ],\n        \"summary\": \"Create new navigation property to onlineMeetings for communications\",\n        \"operationId\": \"communications_CreateOnlineMeetings\",\n        \"requestBody\": {\n          \"description\": \"New navigation property\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.onlineMeeting\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created navigation property.\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.onlineMeeting\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/communications/onlineMeetings/{onlineMeeting-id}\": {\n      \"get\": {\n        \"tags\": [\n          \"communications.onlineMeeting\"\n        ],\n        \"summary\": \"Get onlineMeetings from communications\",\n        \"operationId\": \"communications_GetOnlineMeetings\",\n        \"parameters\": [\n          {\n            \"name\": \"onlineMeeting-id\",\n            \"in\": \"path\",\n            \"description\": \"key: onlineMeeting-id of onlineMeeting\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"onlineMeeting\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"creationDateTime\",\n                  \"startDateTime\",\n                  \"endDateTime\",\n                  \"joinWebUrl\",\n                  \"subject\",\n                  \"participants\",\n                  \"audioConferencing\",\n                  \"chatInfo\",\n                  \"videoTeleconferenceId\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved navigation property\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.onlineMeeting\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        }\n      },\n      \"patch\": {\n        \"tags\": [\n          \"communications.onlineMeeting\"\n        ],\n        \"summary\": \"Update the navigation property onlineMeetings in communications\",\n        \"operationId\": \"communications_UpdateOnlineMeetings\",\n        \"parameters\": [\n          {\n            \"name\": \"onlineMeeting-id\",\n            \"in\": \"path\",\n            \"description\": \"key: onlineMeeting-id of onlineMeeting\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"onlineMeeting\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New navigation property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.onlineMeeting\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    }\n  },\n  \"components\": {\n    \"schemas\": {\n      \"microsoft.graph.cloudCommunications\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"cloudCommunications\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"calls\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.call\"\n                }\n              },\n              \"onlineMeetings\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.onlineMeeting\"\n                }\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"calls\": [\n            {\n              \"@odata.type\": \"microsoft.graph.call\"\n            }\n          ],\n          \"onlineMeetings\": [\n            {\n              \"@odata.type\": \"microsoft.graph.onlineMeeting\"\n            }\n          ]\n        }\n      },\n      \"microsoft.graph.call\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"call\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"state\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.callState\"\n              },\n              \"mediaState\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.callMediaState\"\n              },\n              \"resultInfo\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.resultInfo\"\n              },\n              \"direction\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.callDirection\"\n              },\n              \"subject\": {\n                \"type\": \"string\",\n                \"description\": \"The subject of the conversation.\",\n                \"nullable\": true\n              },\n              \"callbackUri\": {\n                \"type\": \"string\",\n                \"description\": \"The callback URL on which callbacks will be delivered. Must be https.\"\n              },\n              \"callRoutes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.callRoute\"\n                },\n                \"description\": \"The routing information on how the call was retargeted. Read-only.\"\n              },\n              \"source\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.participantInfo\"\n              },\n              \"targets\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.invitationParticipantInfo\"\n                },\n                \"description\": \"The targets of the call. Required information for creating peer to peer call.\"\n              },\n              \"requestedModalities\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.modality\"\n                },\n                \"description\": \"The list of requested modalities. Possible values are: unknown, audio, video, videoBasedScreenSharing, data.\"\n              },\n              \"mediaConfig\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.mediaConfig\"\n              },\n              \"chatInfo\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.chatInfo\"\n              },\n              \"callOptions\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.callOptions\"\n              },\n              \"meetingInfo\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.meetingInfo\"\n              },\n              \"tenantId\": {\n                \"type\": \"string\",\n                \"nullable\": true\n              },\n              \"myParticipantId\": {\n                \"type\": \"string\",\n                \"description\": \"Read-only.\",\n                \"nullable\": true\n              },\n              \"toneInfo\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.toneInfo\"\n              },\n              \"callChainId\": {\n                \"type\": \"string\",\n                \"description\": \"A unique identifier for all the participant calls in a conference or a unique identifier for two participant calls in a P2P call.  This needs to be copied over from Microsoft.Graph.Call.CallChainId.\",\n                \"nullable\": true\n              },\n              \"incomingContext\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.incomingContext\"\n              },\n              \"participants\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.participant\"\n                },\n                \"description\": \"Read-only. Nullable.\"\n              },\n              \"operations\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n                },\n                \"description\": \"Read-only. Nullable.\"\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"state\": {\n            \"@odata.type\": \"microsoft.graph.callState\"\n          },\n          \"mediaState\": {\n            \"@odata.type\": \"microsoft.graph.callMediaState\"\n          },\n          \"resultInfo\": {\n            \"@odata.type\": \"microsoft.graph.resultInfo\"\n          },\n          \"direction\": {\n            \"@odata.type\": \"microsoft.graph.callDirection\"\n          },\n          \"subject\": \"string\",\n          \"callbackUri\": \"string\",\n          \"callRoutes\": [\n            {\n              \"@odata.type\": \"microsoft.graph.callRoute\"\n            }\n          ],\n          \"source\": {\n            \"@odata.type\": \"microsoft.graph.participantInfo\"\n          },\n          \"targets\": [\n            {\n              \"@odata.type\": \"microsoft.graph.invitationParticipantInfo\"\n            }\n          ],\n          \"requestedModalities\": [\n            {\n              \"@odata.type\": \"microsoft.graph.modality\"\n            }\n          ],\n          \"mediaConfig\": {\n            \"@odata.type\": \"microsoft.graph.mediaConfig\"\n          },\n          \"chatInfo\": {\n            \"@odata.type\": \"microsoft.graph.chatInfo\"\n          },\n          \"callOptions\": {\n            \"@odata.type\": \"microsoft.graph.callOptions\"\n          },\n          \"meetingInfo\": {\n            \"@odata.type\": \"microsoft.graph.meetingInfo\"\n          },\n          \"tenantId\": \"string\",\n          \"myParticipantId\": \"string\",\n          \"toneInfo\": {\n            \"@odata.type\": \"microsoft.graph.toneInfo\"\n          },\n          \"callChainId\": \"string\",\n          \"incomingContext\": {\n            \"@odata.type\": \"microsoft.graph.incomingContext\"\n          },\n          \"participants\": [\n            {\n              \"@odata.type\": \"microsoft.graph.participant\"\n            }\n          ],\n          \"operations\": [\n            {\n              \"@odata.type\": \"microsoft.graph.commsOperation\"\n            }\n          ]\n        }\n      },\n      \"microsoft.graph.mediaConfig\": {\n        \"title\": \"mediaConfig\",\n        \"type\": \"object\"\n      },\n      \"microsoft.graph.modality\": {\n        \"title\": \"modality\",\n        \"enum\": [\n          \"audio\",\n          \"video\",\n          \"videoBasedScreenSharing\",\n          \"data\",\n          \"unknownFutureValue\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.screenSharingRole\": {\n        \"title\": \"screenSharingRole\",\n        \"enum\": [\n          \"viewer\",\n          \"sharer\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.muteParticipantOperation\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n          },\n          {\n            \"title\": \"muteParticipantOperation\",\n            \"type\": \"object\"\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"status\": {\n            \"@odata.type\": \"microsoft.graph.operationStatus\"\n          },\n          \"clientContext\": \"string\",\n          \"resultInfo\": {\n            \"@odata.type\": \"microsoft.graph.resultInfo\"\n          }\n        }\n      },\n      \"microsoft.graph.prompt\": {\n        \"title\": \"prompt\",\n        \"type\": \"object\"\n      },\n      \"microsoft.graph.playPromptOperation\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n          },\n          {\n            \"title\": \"playPromptOperation\",\n            \"type\": \"object\"\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"status\": {\n            \"@odata.type\": \"microsoft.graph.operationStatus\"\n          },\n          \"clientContext\": \"string\",\n          \"resultInfo\": {\n            \"@odata.type\": \"microsoft.graph.resultInfo\"\n          }\n        }\n      },\n      \"microsoft.graph.recordOperation\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n          },\n          {\n            \"title\": \"recordOperation\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"recordingLocation\": {\n                \"type\": \"string\",\n                \"description\": \"The location where the recording is located.\",\n                \"nullable\": true\n              },\n              \"recordingAccessToken\": {\n                \"type\": \"string\",\n                \"description\": \"The access token required to retrieve the recording.\",\n                \"nullable\": true\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"status\": {\n            \"@odata.type\": \"microsoft.graph.operationStatus\"\n          },\n          \"clientContext\": \"string\",\n          \"resultInfo\": {\n            \"@odata.type\": \"microsoft.graph.resultInfo\"\n          },\n          \"recordingLocation\": \"string\",\n          \"recordingAccessToken\": \"string\"\n        }\n      },\n      \"microsoft.graph.invitationParticipantInfo\": {\n        \"title\": \"invitationParticipantInfo\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"identity\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identitySet\"\n          },\n          \"replacesCallId\": {\n            \"type\": \"string\",\n            \"description\": \"Optional. The call which the target identity is currently a part of. This call will be dropped once the participant is added.\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"identity\": {\n            \"@odata.type\": \"microsoft.graph.identitySet\"\n          },\n          \"replacesCallId\": \"string\"\n        }\n      },\n      \"microsoft.graph.rejectReason\": {\n        \"title\": \"rejectReason\",\n        \"enum\": [\n          \"none\",\n          \"busy\",\n          \"forbidden\",\n          \"unknownFutureValue\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.subscribeToToneOperation\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n          },\n          {\n            \"title\": \"subscribeToToneOperation\",\n            \"type\": \"object\"\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"status\": {\n            \"@odata.type\": \"microsoft.graph.operationStatus\"\n          },\n          \"clientContext\": \"string\",\n          \"resultInfo\": {\n            \"@odata.type\": \"microsoft.graph.resultInfo\"\n          }\n        }\n      },\n      \"microsoft.graph.unmuteParticipantOperation\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n          },\n          {\n            \"title\": \"unmuteParticipantOperation\",\n            \"type\": \"object\"\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"status\": {\n            \"@odata.type\": \"microsoft.graph.operationStatus\"\n          },\n          \"clientContext\": \"string\",\n          \"resultInfo\": {\n            \"@odata.type\": \"microsoft.graph.resultInfo\"\n          }\n        }\n      },\n      \"microsoft.graph.recordingStatus\": {\n        \"title\": \"recordingStatus\",\n        \"enum\": [\n          \"unknown\",\n          \"notRecording\",\n          \"recording\",\n          \"failed\",\n          \"unknownFutureValue\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.updateRecordingStatusOperation\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n          },\n          {\n            \"title\": \"updateRecordingStatusOperation\",\n            \"type\": \"object\"\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"status\": {\n            \"@odata.type\": \"microsoft.graph.operationStatus\"\n          },\n          \"clientContext\": \"string\",\n          \"resultInfo\": {\n            \"@odata.type\": \"microsoft.graph.resultInfo\"\n          }\n        }\n      },\n      \"microsoft.graph.commsOperation\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"commsOperation\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"status\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.operationStatus\"\n              },\n              \"clientContext\": {\n                \"type\": \"string\",\n                \"description\": \"Unique Client Context string. Max limit is 256 chars.\",\n                \"nullable\": true\n              },\n              \"resultInfo\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.resultInfo\"\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"status\": {\n            \"@odata.type\": \"microsoft.graph.operationStatus\"\n          },\n          \"clientContext\": \"string\",\n          \"resultInfo\": {\n            \"@odata.type\": \"microsoft.graph.resultInfo\"\n          }\n        }\n      },\n      \"microsoft.graph.participant\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"participant\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"info\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.participantInfo\"\n              },\n              \"recordingInfo\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.recordingInfo\"\n              },\n              \"mediaStreams\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.mediaStream\"\n                },\n                \"description\": \"The list of media streams.\"\n              },\n              \"isMuted\": {\n                \"type\": \"boolean\",\n                \"description\": \"true if the participant is muted (client or server muted).\"\n              },\n              \"isInLobby\": {\n                \"type\": \"boolean\",\n                \"description\": \"true if the participant is in lobby.\"\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"info\": {\n            \"@odata.type\": \"microsoft.graph.participantInfo\"\n          },\n          \"recordingInfo\": {\n            \"@odata.type\": \"microsoft.graph.recordingInfo\"\n          },\n          \"mediaStreams\": [\n            {\n              \"@odata.type\": \"microsoft.graph.mediaStream\"\n            }\n          ],\n          \"isMuted\": true,\n          \"isInLobby\": true\n        }\n      },\n      \"microsoft.graph.inviteParticipantsOperation\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.commsOperation\"\n          },\n          {\n            \"title\": \"inviteParticipantsOperation\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"participants\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.invitationParticipantInfo\"\n                },\n                \"description\": \"The participants to invite.\"\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"status\": {\n            \"@odata.type\": \"microsoft.graph.operationStatus\"\n          },\n          \"clientContext\": \"string\",\n          \"resultInfo\": {\n            \"@odata.type\": \"microsoft.graph.resultInfo\"\n          },\n          \"participants\": [\n            {\n              \"@odata.type\": \"microsoft.graph.invitationParticipantInfo\"\n            }\n          ]\n        }\n      },\n      \"microsoft.graph.teleconferenceDeviceQuality\": {\n        \"title\": \"teleconferenceDeviceQuality\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"callChainId\": {\n            \"pattern\": \"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$\",\n            \"type\": \"string\",\n            \"description\": \"A unique identifier for all  the participant calls in a conference or a unique identifier for two participant calls in P2P call. This needs to be copied over from Microsoft.Graph.Call.CallChainId.\",\n            \"format\": \"uuid\"\n          },\n          \"participantId\": {\n            \"pattern\": \"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$\",\n            \"type\": \"string\",\n            \"description\": \"A unique identifier for a specific participant in a conference. The CVI partner needs to copy over Call.MyParticipantId to this property.\",\n            \"format\": \"uuid\"\n          },\n          \"mediaLegId\": {\n            \"pattern\": \"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$\",\n            \"type\": \"string\",\n            \"description\": \"A unique identifier for a specific media leg of a participant in a conference.  One participant can have multiple media leg identifiers if retargeting happens. CVI partner assigns this value.\",\n            \"format\": \"uuid\"\n          },\n          \"deviceName\": {\n            \"type\": \"string\",\n            \"description\": \"The user media agent name, such as Cisco SX80.\"\n          },\n          \"deviceDescription\": {\n            \"type\": \"string\",\n            \"description\": \"Any additional description, such as VTC Bldg 30/21.\"\n          },\n          \"cloudServiceName\": {\n            \"type\": \"string\",\n            \"description\": \"The Azure deployed cloud service name, such as contoso.cloudapp.net.\",\n            \"nullable\": true\n          },\n          \"cloudServiceInstanceName\": {\n            \"type\": \"string\",\n            \"description\": \"The Azure deployed cloud service instance name, such as FrontEnd_IN_3.\",\n            \"nullable\": true\n          },\n          \"cloudServiceDeploymentId\": {\n            \"type\": \"string\",\n            \"description\": \"A unique deployment identifier assigned by Azure.\",\n            \"nullable\": true\n          },\n          \"cloudServiceDeploymentEnvironment\": {\n            \"type\": \"string\",\n            \"description\": \"A geo-region where the service is deployed, such as ProdNoam.\",\n            \"nullable\": true\n          },\n          \"mediaQualityList\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"$ref\": \"#/components/schemas/microsoft.graph.teleconferenceDeviceMediaQuality\"\n            },\n            \"description\": \"The list of media qualities in a media session (call), such as audio quality, video quality, and/or screen sharing quality.\"\n          }\n        },\n        \"example\": {\n          \"callChainId\": \"string\",\n          \"participantId\": \"string\",\n          \"mediaLegId\": \"string\",\n          \"deviceName\": \"string\",\n          \"deviceDescription\": \"string\",\n          \"cloudServiceName\": \"string\",\n          \"cloudServiceInstanceName\": \"string\",\n          \"cloudServiceDeploymentId\": \"string\",\n          \"cloudServiceDeploymentEnvironment\": \"string\",\n          \"mediaQualityList\": [\n            {\n              \"@odata.type\": \"microsoft.graph.teleconferenceDeviceMediaQuality\"\n            }\n          ]\n        }\n      },\n      \"microsoft.graph.onlineMeeting\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"onlineMeeting\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"creationDateTime\": {\n                \"pattern\": \"^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$\",\n                \"type\": \"string\",\n                \"description\": \"The meeting creation time in UTC. Read-only.\",\n                \"format\": \"date-time\",\n                \"nullable\": true\n              },\n              \"startDateTime\": {\n                \"pattern\": \"^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$\",\n                \"type\": \"string\",\n                \"description\": \"The meeting start time in UTC.\",\n                \"format\": \"date-time\",\n                \"nullable\": true\n              },\n              \"endDateTime\": {\n                \"pattern\": \"^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$\",\n                \"type\": \"string\",\n                \"description\": \"The meeting end time in UTC.\",\n                \"format\": \"date-time\",\n                \"nullable\": true\n              },\n              \"joinWebUrl\": {\n                \"type\": \"string\",\n                \"description\": \"The join URL of the online meeting. Read-only.\",\n                \"nullable\": true\n              },\n              \"subject\": {\n                \"type\": \"string\",\n                \"description\": \"The subject of the online meeting.\",\n                \"nullable\": true\n              },\n              \"participants\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.meetingParticipants\"\n              },\n              \"audioConferencing\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.audioConferencing\"\n              },\n              \"chatInfo\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.chatInfo\"\n              },\n              \"videoTeleconferenceId\": {\n                \"type\": \"string\",\n                \"description\": \"The video teleconferencing ID. Read-only.\",\n                \"nullable\": true\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"creationDateTime\": \"string (timestamp)\",\n          \"startDateTime\": \"string (timestamp)\",\n          \"endDateTime\": \"string (timestamp)\",\n          \"joinWebUrl\": \"string\",\n          \"subject\": \"string\",\n          \"participants\": {\n            \"@odata.type\": \"microsoft.graph.meetingParticipants\"\n          },\n          \"audioConferencing\": {\n            \"@odata.type\": \"microsoft.graph.audioConferencing\"\n          },\n          \"chatInfo\": {\n            \"@odata.type\": \"microsoft.graph.chatInfo\"\n          },\n          \"videoTeleconferenceId\": \"string\"\n        }\n      },\n      \"microsoft.graph.entity\": {\n        \"title\": \"entity\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"id\": {\n            \"type\": \"string\",\n            \"description\": \"Read-only.\"\n          }\n        },\n        \"example\": {\n          \"id\": \"string (identifier)\"\n        }\n      },\n      \"microsoft.graph.callState\": {\n        \"title\": \"callState\",\n        \"enum\": [\n          \"incoming\",\n          \"establishing\",\n          \"established\",\n          \"hold\",\n          \"transferring\",\n          \"transferAccepted\",\n          \"redirecting\",\n          \"terminating\",\n          \"terminated\",\n          \"unknownFutureValue\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.callMediaState\": {\n        \"title\": \"callMediaState\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"audio\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.mediaState\"\n          }\n        },\n        \"example\": {\n          \"audio\": {\n            \"@odata.type\": \"microsoft.graph.mediaState\"\n          }\n        }\n      },\n      \"microsoft.graph.resultInfo\": {\n        \"title\": \"resultInfo\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"code\": {\n            \"maximum\": 2147483647,\n            \"minimum\": -2147483648,\n            \"type\": \"integer\",\n            \"description\": \"The result code.\",\n            \"format\": \"int32\"\n          },\n          \"subcode\": {\n            \"maximum\": 2147483647,\n            \"minimum\": -2147483648,\n            \"type\": \"integer\",\n            \"description\": \"The result sub-code.\",\n            \"format\": \"int32\"\n          },\n          \"message\": {\n            \"type\": \"string\",\n            \"description\": \"The message.\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"code\": \"integer\",\n          \"subcode\": \"integer\",\n          \"message\": \"string\"\n        }\n      },\n      \"microsoft.graph.callDirection\": {\n        \"title\": \"callDirection\",\n        \"enum\": [\n          \"incoming\",\n          \"outgoing\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.callRoute\": {\n        \"title\": \"callRoute\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"routingType\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.routingType\"\n          },\n          \"original\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identitySet\"\n          },\n          \"final\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identitySet\"\n          }\n        },\n        \"example\": {\n          \"routingType\": {\n            \"@odata.type\": \"microsoft.graph.routingType\"\n          },\n          \"original\": {\n            \"@odata.type\": \"microsoft.graph.identitySet\"\n          },\n          \"final\": {\n            \"@odata.type\": \"microsoft.graph.identitySet\"\n          }\n        }\n      },\n      \"microsoft.graph.participantInfo\": {\n        \"title\": \"participantInfo\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"identity\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identitySet\"\n          },\n          \"endpointType\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.endpointType\"\n          },\n          \"region\": {\n            \"type\": \"string\",\n            \"description\": \"The home region of the participant. This can be a country, a continent, or a larger geographic region. This does not change based on the participant's current physical location. Read-only.\",\n            \"nullable\": true\n          },\n          \"languageId\": {\n            \"type\": \"string\",\n            \"description\": \"The language culture string. Read-only.\",\n            \"nullable\": true\n          },\n          \"countryCode\": {\n            \"type\": \"string\",\n            \"description\": \"The ISO 3166-1 Alpha-2 country code of the participant's best estimated physical location at the start of the call. Read-only.\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"identity\": {\n            \"@odata.type\": \"microsoft.graph.identitySet\"\n          },\n          \"endpointType\": {\n            \"@odata.type\": \"microsoft.graph.endpointType\"\n          },\n          \"region\": \"string\",\n          \"languageId\": \"string\",\n          \"countryCode\": \"string\"\n        }\n      },\n      \"microsoft.graph.chatInfo\": {\n        \"title\": \"chatInfo\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"threadId\": {\n            \"type\": \"string\",\n            \"description\": \"The unique identifier for a thread in Microsoft Teams.\",\n            \"nullable\": true\n          },\n          \"messageId\": {\n            \"type\": \"string\",\n            \"description\": \"The unique identifier of a message in a Microsoft Teams channel.\",\n            \"nullable\": true\n          },\n          \"replyChainMessageId\": {\n            \"type\": \"string\",\n            \"description\": \"The ID of the reply message.\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"threadId\": \"string\",\n          \"messageId\": \"string\",\n          \"replyChainMessageId\": \"string\"\n        }\n      },\n      \"microsoft.graph.callOptions\": {\n        \"title\": \"callOptions\",\n        \"type\": \"object\"\n      },\n      \"microsoft.graph.meetingInfo\": {\n        \"title\": \"meetingInfo\",\n        \"type\": \"object\"\n      },\n      \"microsoft.graph.toneInfo\": {\n        \"title\": \"toneInfo\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"sequenceId\": {\n            \"type\": \"integer\",\n            \"description\": \"An incremental identifier used for ordering DTMF events.\",\n            \"format\": \"int64\"\n          },\n          \"tone\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.tone\"\n          }\n        },\n        \"example\": {\n          \"sequenceId\": \"integer\",\n          \"tone\": {\n            \"@odata.type\": \"microsoft.graph.tone\"\n          }\n        }\n      },\n      \"microsoft.graph.incomingContext\": {\n        \"title\": \"incomingContext\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"sourceParticipantId\": {\n            \"type\": \"string\",\n            \"description\": \"The ID of the participant that triggered the incoming call. Read-only.\",\n            \"nullable\": true\n          },\n          \"observedParticipantId\": {\n            \"type\": \"string\",\n            \"description\": \"The ID of the participant that is under observation. Read-only.\",\n            \"nullable\": true\n          },\n          \"onBehalfOf\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identitySet\"\n          },\n          \"transferor\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identitySet\"\n          }\n        },\n        \"example\": {\n          \"sourceParticipantId\": \"string\",\n          \"observedParticipantId\": \"string\",\n          \"onBehalfOf\": {\n            \"@odata.type\": \"microsoft.graph.identitySet\"\n          },\n          \"transferor\": {\n            \"@odata.type\": \"microsoft.graph.identitySet\"\n          }\n        }\n      },\n      \"microsoft.graph.identitySet\": {\n        \"title\": \"identitySet\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"application\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identity\"\n          },\n          \"device\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identity\"\n          },\n          \"user\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identity\"\n          }\n        },\n        \"example\": {\n          \"application\": {\n            \"@odata.type\": \"microsoft.graph.identity\"\n          },\n          \"device\": {\n            \"@odata.type\": \"microsoft.graph.identity\"\n          },\n          \"user\": {\n            \"@odata.type\": \"microsoft.graph.identity\"\n          }\n        }\n      },\n      \"microsoft.graph.operationStatus\": {\n        \"title\": \"operationStatus\",\n        \"enum\": [\n          \"NotStarted\",\n          \"Running\",\n          \"Completed\",\n          \"Failed\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.recordingInfo\": {\n        \"title\": \"recordingInfo\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"recordingStatus\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.recordingStatus\"\n          },\n          \"initiator\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identitySet\"\n          }\n        },\n        \"example\": {\n          \"recordingStatus\": {\n            \"@odata.type\": \"microsoft.graph.recordingStatus\"\n          },\n          \"initiator\": {\n            \"@odata.type\": \"microsoft.graph.identitySet\"\n          }\n        }\n      },\n      \"microsoft.graph.mediaStream\": {\n        \"title\": \"mediaStream\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"mediaType\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.modality\"\n          },\n          \"label\": {\n            \"type\": \"string\",\n            \"description\": \"The media stream label.\",\n            \"nullable\": true\n          },\n          \"sourceId\": {\n            \"type\": \"string\",\n            \"description\": \"The source ID.\"\n          },\n          \"direction\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.mediaDirection\"\n          },\n          \"serverMuted\": {\n            \"type\": \"boolean\",\n            \"description\": \"If the media is muted by the server.\"\n          }\n        },\n        \"example\": {\n          \"mediaType\": {\n            \"@odata.type\": \"microsoft.graph.modality\"\n          },\n          \"label\": \"string\",\n          \"sourceId\": \"string\",\n          \"direction\": {\n            \"@odata.type\": \"microsoft.graph.mediaDirection\"\n          },\n          \"serverMuted\": true\n        }\n      },\n      \"microsoft.graph.teleconferenceDeviceMediaQuality\": {\n        \"title\": \"teleconferenceDeviceMediaQuality\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"channelIndex\": {\n            \"maximum\": 2147483647,\n            \"minimum\": -2147483648,\n            \"type\": \"integer\",\n            \"description\": \"The channel index of media. Indexing begins with 1.  If a media session contains 3 video modalities, channel indexes will be 1, 2, and 3.\",\n            \"format\": \"int32\"\n          },\n          \"mediaDuration\": {\n            \"pattern\": \"^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$\",\n            \"type\": \"string\",\n            \"description\": \"The total modality duration. If the media enabled and disabled multiple times, MediaDuration will the summation of all of the durations.\",\n            \"format\": \"duration\",\n            \"nullable\": true\n          },\n          \"networkLinkSpeedInBytes\": {\n            \"type\": \"integer\",\n            \"description\": \"The network link speed in bytes\",\n            \"format\": \"int64\",\n            \"nullable\": true\n          },\n          \"localIPAddress\": {\n            \"type\": \"string\",\n            \"description\": \"the local IP address for the media session.\",\n            \"nullable\": true\n          },\n          \"localPort\": {\n            \"maximum\": 2147483647,\n            \"minimum\": -2147483648,\n            \"type\": \"integer\",\n            \"description\": \"The local media port.\",\n            \"format\": \"int32\",\n            \"nullable\": true\n          },\n          \"remoteIPAddress\": {\n            \"type\": \"string\",\n            \"description\": \"The remote IP address for the media session.\",\n            \"nullable\": true\n          },\n          \"remotePort\": {\n            \"maximum\": 2147483647,\n            \"minimum\": -2147483648,\n            \"type\": \"integer\",\n            \"description\": \"The remote media port.\",\n            \"format\": \"int32\",\n            \"nullable\": true\n          },\n          \"inboundPackets\": {\n            \"type\": \"integer\",\n            \"description\": \"The total number of the inbound packets.\",\n            \"format\": \"int64\",\n            \"nullable\": true\n          },\n          \"outboundPackets\": {\n            \"type\": \"integer\",\n            \"description\": \"The total number of the outbound packets.\",\n            \"format\": \"int64\",\n            \"nullable\": true\n          },\n          \"averageInboundPacketLossRateInPercentage\": {\n            \"type\": \"number\",\n            \"description\": \"The average inbound stream packet loss rate in percentage (0-100). For example, 0.01 means 0.01%.\",\n            \"format\": \"double\",\n            \"nullable\": true\n          },\n          \"averageOutboundPacketLossRateInPercentage\": {\n            \"type\": \"number\",\n            \"description\": \"The average outbound stream packet loss rate in percentage (0-100). For example, 0.01 means 0.01%.\",\n            \"format\": \"double\",\n            \"nullable\": true\n          },\n          \"maximumInboundPacketLossRateInPercentage\": {\n            \"type\": \"number\",\n            \"description\": \"The maximum inbound stream packet loss rate in percentage (0-100). For example, 0.01 means 0.01%.\",\n            \"format\": \"double\",\n            \"nullable\": true\n          },\n          \"maximumOutboundPacketLossRateInPercentage\": {\n            \"type\": \"number\",\n            \"description\": \"The maximum outbound stream packet loss rate in percentage (0-100). For example, 0.01 means 0.01%.\",\n            \"format\": \"double\",\n            \"nullable\": true\n          },\n          \"averageInboundRoundTripDelay\": {\n            \"pattern\": \"^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$\",\n            \"type\": \"string\",\n            \"description\": \"The average inbound stream network round trip delay.\",\n            \"format\": \"duration\",\n            \"nullable\": true\n          },\n          \"averageOutboundRoundTripDelay\": {\n            \"pattern\": \"^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$\",\n            \"type\": \"string\",\n            \"description\": \"The average outbound stream network round trip delay.\",\n            \"format\": \"duration\",\n            \"nullable\": true\n          },\n          \"maximumInboundRoundTripDelay\": {\n            \"pattern\": \"^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$\",\n            \"type\": \"string\",\n            \"description\": \"The maximum inbound stream network round trip delay.\",\n            \"format\": \"duration\",\n            \"nullable\": true\n          },\n          \"maximumOutboundRoundTripDelay\": {\n            \"pattern\": \"^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$\",\n            \"type\": \"string\",\n            \"description\": \"The maximum outbound stream network round trip delay.\",\n            \"format\": \"duration\",\n            \"nullable\": true\n          },\n          \"averageInboundJitter\": {\n            \"pattern\": \"^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$\",\n            \"type\": \"string\",\n            \"description\": \"The average inbound stream network jitter.\",\n            \"format\": \"duration\",\n            \"nullable\": true\n          },\n          \"averageOutboundJitter\": {\n            \"pattern\": \"^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$\",\n            \"type\": \"string\",\n            \"description\": \"The average outbound stream network jitter.\",\n            \"format\": \"duration\",\n            \"nullable\": true\n          },\n          \"maximumInboundJitter\": {\n            \"pattern\": \"^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$\",\n            \"type\": \"string\",\n            \"description\": \"The maximum inbound stream network jitter.\",\n            \"format\": \"duration\",\n            \"nullable\": true\n          },\n          \"maximumOutboundJitter\": {\n            \"pattern\": \"^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$\",\n            \"type\": \"string\",\n            \"description\": \"The maximum outbound stream network jitter.\",\n            \"format\": \"duration\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"channelIndex\": \"integer\",\n          \"mediaDuration\": \"string\",\n          \"networkLinkSpeedInBytes\": \"integer\",\n          \"localIPAddress\": \"string\",\n          \"localPort\": \"integer\",\n          \"remoteIPAddress\": \"string\",\n          \"remotePort\": \"integer\",\n          \"inboundPackets\": \"integer\",\n          \"outboundPackets\": \"integer\",\n          \"averageInboundPacketLossRateInPercentage\": \"double\",\n          \"averageOutboundPacketLossRateInPercentage\": \"double\",\n          \"maximumInboundPacketLossRateInPercentage\": \"double\",\n          \"maximumOutboundPacketLossRateInPercentage\": \"double\",\n          \"averageInboundRoundTripDelay\": \"string\",\n          \"averageOutboundRoundTripDelay\": \"string\",\n          \"maximumInboundRoundTripDelay\": \"string\",\n          \"maximumOutboundRoundTripDelay\": \"string\",\n          \"averageInboundJitter\": \"string\",\n          \"averageOutboundJitter\": \"string\",\n          \"maximumInboundJitter\": \"string\",\n          \"maximumOutboundJitter\": \"string\"\n        }\n      },\n      \"microsoft.graph.meetingParticipants\": {\n        \"title\": \"meetingParticipants\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"organizer\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.meetingParticipantInfo\"\n          },\n          \"attendees\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"$ref\": \"#/components/schemas/microsoft.graph.meetingParticipantInfo\"\n            }\n          }\n        },\n        \"example\": {\n          \"organizer\": {\n            \"@odata.type\": \"microsoft.graph.meetingParticipantInfo\"\n          },\n          \"attendees\": [\n            {\n              \"@odata.type\": \"microsoft.graph.meetingParticipantInfo\"\n            }\n          ]\n        }\n      },\n      \"microsoft.graph.audioConferencing\": {\n        \"title\": \"audioConferencing\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"conferenceId\": {\n            \"type\": \"string\",\n            \"nullable\": true\n          },\n          \"tollNumber\": {\n            \"type\": \"string\",\n            \"description\": \"The toll number that connects to the Audio Conference Provider.\",\n            \"nullable\": true\n          },\n          \"tollFreeNumber\": {\n            \"type\": \"string\",\n            \"description\": \"The toll-free number that connects to the Audio Conference Provider.\",\n            \"nullable\": true\n          },\n          \"dialinUrl\": {\n            \"type\": \"string\",\n            \"description\": \"A URL to the externally-accessible web page that contains dial-in information.\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"conferenceId\": \"string\",\n          \"tollNumber\": \"string\",\n          \"tollFreeNumber\": \"string\",\n          \"dialinUrl\": \"string\"\n        }\n      },\n      \"odata.error\": {\n        \"required\": [\n          \"error\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"error\": {\n            \"$ref\": \"#/components/schemas/odata.error.main\"\n          }\n        }\n      },\n      \"microsoft.graph.mediaState\": {\n        \"title\": \"mediaState\",\n        \"enum\": [\n          \"active\",\n          \"inactive\",\n          \"unknownFutureValue\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.routingType\": {\n        \"title\": \"routingType\",\n        \"enum\": [\n          \"forwarded\",\n          \"lookup\",\n          \"selfFork\",\n          \"unknownFutureValue\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.endpointType\": {\n        \"title\": \"endpointType\",\n        \"enum\": [\n          \"default\",\n          \"voicemail\",\n          \"skypeForBusiness\",\n          \"skypeForBusinessVoipPhone\",\n          \"unknownFutureValue\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.tone\": {\n        \"title\": \"tone\",\n        \"enum\": [\n          \"tone0\",\n          \"tone1\",\n          \"tone2\",\n          \"tone3\",\n          \"tone4\",\n          \"tone5\",\n          \"tone6\",\n          \"tone7\",\n          \"tone8\",\n          \"tone9\",\n          \"star\",\n          \"pound\",\n          \"a\",\n          \"b\",\n          \"c\",\n          \"d\",\n          \"flash\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.identity\": {\n        \"title\": \"identity\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"displayName\": {\n            \"type\": \"string\",\n            \"description\": \"The identity's display name. Note that this may not always be available or up to date. For example, if a user changes their display name, the API may show the new value in a future response, but the items associated with the user won't show up as having changed when using delta.\",\n            \"nullable\": true\n          },\n          \"id\": {\n            \"type\": \"string\",\n            \"description\": \"Unique identifier for the identity.\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"displayName\": \"string\",\n          \"id\": \"string\"\n        }\n      },\n      \"microsoft.graph.mediaDirection\": {\n        \"title\": \"mediaDirection\",\n        \"enum\": [\n          \"inactive\",\n          \"sendOnly\",\n          \"receiveOnly\",\n          \"sendReceive\"\n        ],\n        \"type\": \"string\"\n      },\n      \"microsoft.graph.meetingParticipantInfo\": {\n        \"title\": \"meetingParticipantInfo\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"identity\": {\n            \"$ref\": \"#/components/schemas/microsoft.graph.identitySet\"\n          },\n          \"upn\": {\n            \"type\": \"string\",\n            \"description\": \"User principal name of the participant.\",\n            \"nullable\": true\n          }\n        },\n        \"example\": {\n          \"identity\": {\n            \"@odata.type\": \"microsoft.graph.identitySet\"\n          },\n          \"upn\": \"string\"\n        }\n      },\n      \"odata.error.main\": {\n        \"required\": [\n          \"code\",\n          \"message\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"code\": {\n            \"type\": \"string\"\n          },\n          \"message\": {\n            \"type\": \"string\"\n          },\n          \"target\": {\n            \"type\": \"string\"\n          },\n          \"details\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"$ref\": \"#/components/schemas/odata.error.detail\"\n            }\n          },\n          \"innererror\": {\n            \"type\": \"object\",\n            \"description\": \"The structure of this object is service-specific\"\n          }\n        }\n      },\n      \"odata.error.detail\": {\n        \"required\": [\n          \"code\",\n          \"message\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"code\": {\n            \"type\": \"string\"\n          },\n          \"message\": {\n            \"type\": \"string\"\n          },\n          \"target\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"responses\": {\n      \"error\": {\n        \"description\": \"error\",\n        \"content\": {\n          \"application/json\": {\n            \"schema\": {\n              \"$ref\": \"#/components/schemas/odata.error\"\n            }\n          }\n        }\n      }\n    },\n    \"parameters\": {\n      \"top\": {\n        \"name\": \"$top\",\n        \"in\": \"query\",\n        \"description\": \"Show only the first n items\",\n        \"schema\": {\n          \"minimum\": 0,\n          \"type\": \"integer\"\n        },\n        \"example\": 50\n      },\n      \"skip\": {\n        \"name\": \"$skip\",\n        \"in\": \"query\",\n        \"description\": \"Skip the first n items\",\n        \"schema\": {\n          \"minimum\": 0,\n          \"type\": \"integer\"\n        }\n      },\n      \"search\": {\n        \"name\": \"$search\",\n        \"in\": \"query\",\n        \"description\": \"Search items by search phrases\",\n        \"schema\": {\n          \"type\": \"string\"\n        }\n      },\n      \"filter\": {\n        \"name\": \"$filter\",\n        \"in\": \"query\",\n        \"description\": \"Filter items by property values\",\n        \"schema\": {\n          \"type\": \"string\"\n        }\n      },\n      \"count\": {\n        \"name\": \"$count\",\n        \"in\": \"query\",\n        \"description\": \"Include count of items\",\n        \"schema\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"securitySchemes\": {\n      \"azureaadv2\": {\n        \"type\": \"oauth2\",\n        \"flows\": {\n          \"authorizationCode\": {\n            \"authorizationUrl\": \"https://login.microsoftonline.com/common/oauth2/v2.0/authorize\",\n            \"tokenUrl\": \"https://login.microsoftonline.com/common/oauth2/v2.0/token\",\n            \"scopes\": {}\n          }\n        }\n      }\n    }\n  },\n  \"security\": [\n    {\n      \"azureaadv2\": []\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Resources/OpenApiDescriptions/MicrosoftGraph.PowershellSdk.CloudCommunications.yml",
    "content": "# Originally from https://github.com/microsoftgraph/msgraph-sdk-powershell/blob/dev/openApiDocs/v1.0/CloudCommunications.yml\n\nopenapi: 3.0.1\ninfo:\n  title: CloudCommunications\n  version: v1.0\nservers:\n  - url: https://graph.microsoft.com/v1.0/\n    description: Core\npaths:\n  /communications:\n    get:\n      tags:\n        - communications.cloudCommunications\n      summary: Get communications\n      operationId: communications.cloudCommunications_GetCloudCommunications\n      parameters:\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - calls\n                - onlineMeetings\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - calls\n                - onlineMeetings\n              type: string\n      responses:\n        '200':\n          description: Retrieved entity\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.cloudCommunications'\n          links:\n            calls:\n              operationId: communications.GetCalls\n              parameters:\n                call-id: $response.body#/id\n            onlineMeetings:\n              operationId: communications.GetOnlineMeetings\n              parameters:\n                onlineMeeting-id: $response.body#/id\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n    patch:\n      tags:\n        - communications.cloudCommunications\n      summary: Update communications\n      operationId: communications.cloudCommunications_UpdateCloudCommunications\n      requestBody:\n        description: New property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.cloudCommunications'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  /communications/calls:\n    get:\n      tags:\n        - communications.call\n      summary: Get calls from communications\n      operationId: communications_ListCalls\n      parameters:\n        - $ref: '#/components/parameters/top'\n        - $ref: '#/components/parameters/skip'\n        - $ref: '#/components/parameters/search'\n        - $ref: '#/components/parameters/filter'\n        - $ref: '#/components/parameters/count'\n        - name: $orderby\n          in: query\n          description: Order items by property values\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - id desc\n                - state\n                - state desc\n                - mediaState\n                - mediaState desc\n                - resultInfo\n                - resultInfo desc\n                - direction\n                - direction desc\n                - subject\n                - subject desc\n                - callbackUri\n                - callbackUri desc\n                - callRoutes\n                - callRoutes desc\n                - source\n                - source desc\n                - targets\n                - targets desc\n                - requestedModalities\n                - requestedModalities desc\n                - mediaConfig\n                - mediaConfig desc\n                - chatInfo\n                - chatInfo desc\n                - callOptions\n                - callOptions desc\n                - meetingInfo\n                - meetingInfo desc\n                - tenantId\n                - tenantId desc\n                - myParticipantId\n                - myParticipantId desc\n                - toneInfo\n                - toneInfo desc\n                - callChainId\n                - callChainId desc\n                - incomingContext\n                - incomingContext desc\n              type: string\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - state\n                - mediaState\n                - resultInfo\n                - direction\n                - subject\n                - callbackUri\n                - callRoutes\n                - source\n                - targets\n                - requestedModalities\n                - mediaConfig\n                - chatInfo\n                - callOptions\n                - meetingInfo\n                - tenantId\n                - myParticipantId\n                - toneInfo\n                - callChainId\n                - incomingContext\n                - participants\n                - operations\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - participants\n                - operations\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                title: Collection of call\n                type: object\n                properties:\n                  value:\n                    type: array\n                    items:\n                      $ref: '#/components/schemas/microsoft.graph.call'\n                  '@odata.nextLink':\n                    type: string\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-pageable:\n        nextLinkName: '@odata.nextLink'\n        operationName: listMore\n      x-ms-docs-operation-type: operation\n    post:\n      tags:\n        - communications.call\n      summary: Create new navigation property to calls for communications\n      operationId: communications_CreateCalls\n      requestBody:\n        description: New navigation property\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.call'\n        required: true\n      responses:\n        '201':\n          description: Created navigation property.\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.call'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/communications/calls/{call-id}':\n    get:\n      tags:\n        - communications.call\n      summary: Get calls from communications\n      operationId: communications_GetCalls\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - state\n                - mediaState\n                - resultInfo\n                - direction\n                - subject\n                - callbackUri\n                - callRoutes\n                - source\n                - targets\n                - requestedModalities\n                - mediaConfig\n                - chatInfo\n                - callOptions\n                - meetingInfo\n                - tenantId\n                - myParticipantId\n                - toneInfo\n                - callChainId\n                - incomingContext\n                - participants\n                - operations\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n                - participants\n                - operations\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.call'\n          links:\n            participants:\n              operationId: cloudCommunications.calls.GetParticipants\n              parameters:\n                call-id: $request.path.call-id\n                participant-id: $response.body#/id\n            operations:\n              operationId: cloudCommunications.calls.GetOperations\n              parameters:\n                call-id: $request.path.call-id\n                commsOperation-id: $response.body#/id\n        default:\n          $ref: '#/components/responses/error'\n    patch:\n      tags:\n        - communications.call\n      summary: Update the navigation property calls in communications\n      operationId: communications_UpdateCalls\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: New navigation property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.call'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/communications/calls/{call-id}/microsoft.graph.answer':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action answer\n      operationId: communications.calls_answer\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                callbackUri:\n                  type: string\n                mediaConfig:\n                  $ref: '#/components/schemas/microsoft.graph.mediaConfig'\n                acceptedModalities:\n                  type: array\n                  items:\n                    $ref: '#/components/schemas/microsoft.graph.modality'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.changeScreenSharingRole':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action changeScreenSharingRole\n      operationId: communications.calls_changeScreenSharingRole\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                role:\n                  $ref: '#/components/schemas/microsoft.graph.screenSharingRole'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.keepAlive':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action keepAlive\n      operationId: communications.calls_keepAlive\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.mute':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action mute\n      operationId: communications.calls_mute\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                clientContext:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '200':\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.muteParticipantOperation'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.playPrompt':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action playPrompt\n      operationId: communications.calls_playPrompt\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                prompts:\n                  type: array\n                  items:\n                    $ref: '#/components/schemas/microsoft.graph.prompt'\n                clientContext:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '200':\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.playPromptOperation'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.recordResponse':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action recordResponse\n      operationId: communications.calls_recordResponse\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                prompts:\n                  type: array\n                  items:\n                    $ref: '#/components/schemas/microsoft.graph.prompt'\n                bargeInAllowed:\n                  type: boolean\n                  default: false\n                  nullable: true\n                initialSilenceTimeoutInSeconds:\n                  maximum: 2147483647\n                  minimum: -2147483648\n                  type: integer\n                  format: int32\n                  nullable: true\n                maxSilenceTimeoutInSeconds:\n                  maximum: 2147483647\n                  minimum: -2147483648\n                  type: integer\n                  format: int32\n                  nullable: true\n                maxRecordDurationInSeconds:\n                  maximum: 2147483647\n                  minimum: -2147483648\n                  type: integer\n                  format: int32\n                  nullable: true\n                playBeep:\n                  type: boolean\n                  default: false\n                  nullable: true\n                stopTones:\n                  type: array\n                  items:\n                    type: string\n                    nullable: true\n                clientContext:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '200':\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.recordOperation'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.redirect':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action redirect\n      operationId: communications.calls_redirect\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                targets:\n                  type: array\n                  items:\n                    $ref: '#/components/schemas/microsoft.graph.invitationParticipantInfo'\n                timeout:\n                  maximum: 2147483647\n                  minimum: -2147483648\n                  type: integer\n                  format: int32\n                  nullable: true\n                callbackUri:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.reject':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action reject\n      operationId: communications.calls_reject\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                reason:\n                  $ref: '#/components/schemas/microsoft.graph.rejectReason'\n                callbackUri:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.subscribeToTone':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action subscribeToTone\n      operationId: communications.calls_subscribeToTone\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                clientContext:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '200':\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.subscribeToToneOperation'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.transfer':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action transfer\n      operationId: communications.calls_transfer\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                transferTarget:\n                  $ref: '#/components/schemas/microsoft.graph.invitationParticipantInfo'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.unmute':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action unmute\n      operationId: communications.calls_unmute\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                clientContext:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '200':\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.unmuteParticipantOperation'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/microsoft.graph.updateRecordingStatus':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action updateRecordingStatus\n      operationId: communications.calls_updateRecordingStatus\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                status:\n                  $ref: '#/components/schemas/microsoft.graph.recordingStatus'\n                clientContext:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '200':\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.updateRecordingStatusOperation'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/operations':\n    get:\n      tags:\n        - communications.call\n      summary: Get operations from communications\n      operationId: communications.calls_ListOperations\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n        - $ref: '#/components/parameters/top'\n        - $ref: '#/components/parameters/skip'\n        - $ref: '#/components/parameters/search'\n        - $ref: '#/components/parameters/filter'\n        - $ref: '#/components/parameters/count'\n        - name: $orderby\n          in: query\n          description: Order items by property values\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - id desc\n                - status\n                - status desc\n                - clientContext\n                - clientContext desc\n                - resultInfo\n                - resultInfo desc\n              type: string\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - status\n                - clientContext\n                - resultInfo\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                title: Collection of commsOperation\n                type: object\n                properties:\n                  value:\n                    type: array\n                    items:\n                      $ref: '#/components/schemas/microsoft.graph.commsOperation'\n                  '@odata.nextLink':\n                    type: string\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-pageable:\n        nextLinkName: '@odata.nextLink'\n        operationName: listMore\n      x-ms-docs-operation-type: operation\n    post:\n      tags:\n        - communications.call\n      summary: Create new navigation property to operations for communications\n      operationId: communications.calls_CreateOperations\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: New navigation property\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        required: true\n      responses:\n        '201':\n          description: Created navigation property.\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/communications/calls/{call-id}/operations/{commsOperation-id}':\n    get:\n      tags:\n        - communications.call\n      summary: Get operations from communications\n      operationId: communications.calls_GetOperations\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n        - name: commsOperation-id\n          in: path\n          description: 'key: commsOperation-id of commsOperation'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: commsOperation\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - status\n                - clientContext\n                - resultInfo\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        default:\n          $ref: '#/components/responses/error'\n    patch:\n      tags:\n        - communications.call\n      summary: Update the navigation property operations in communications\n      operationId: communications.calls_UpdateOperations\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n        - name: commsOperation-id\n          in: path\n          description: 'key: commsOperation-id of commsOperation'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: commsOperation\n      requestBody:\n        description: New navigation property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/communications/calls/{call-id}/participants':\n    get:\n      tags:\n        - communications.call\n      summary: Get participants from communications\n      operationId: communications.calls_ListParticipants\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n        - $ref: '#/components/parameters/top'\n        - $ref: '#/components/parameters/skip'\n        - $ref: '#/components/parameters/search'\n        - $ref: '#/components/parameters/filter'\n        - $ref: '#/components/parameters/count'\n        - name: $orderby\n          in: query\n          description: Order items by property values\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - id desc\n                - info\n                - info desc\n                - recordingInfo\n                - recordingInfo desc\n                - mediaStreams\n                - mediaStreams desc\n                - isMuted\n                - isMuted desc\n                - isInLobby\n                - isInLobby desc\n              type: string\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - info\n                - recordingInfo\n                - mediaStreams\n                - isMuted\n                - isInLobby\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                title: Collection of participant\n                type: object\n                properties:\n                  value:\n                    type: array\n                    items:\n                      $ref: '#/components/schemas/microsoft.graph.participant'\n                  '@odata.nextLink':\n                    type: string\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-pageable:\n        nextLinkName: '@odata.nextLink'\n        operationName: listMore\n      x-ms-docs-operation-type: operation\n    post:\n      tags:\n        - communications.call\n      summary: Create new navigation property to participants for communications\n      operationId: communications.calls_CreateParticipants\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: New navigation property\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.participant'\n        required: true\n      responses:\n        '201':\n          description: Created navigation property.\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.participant'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/communications/calls/{call-id}/participants/{participant-id}':\n    get:\n      tags:\n        - communications.call\n      summary: Get participants from communications\n      operationId: communications.calls_GetParticipants\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n        - name: participant-id\n          in: path\n          description: 'key: participant-id of participant'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: participant\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - info\n                - recordingInfo\n                - mediaStreams\n                - isMuted\n                - isInLobby\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.participant'\n        default:\n          $ref: '#/components/responses/error'\n    patch:\n      tags:\n        - communications.call\n      summary: Update the navigation property participants in communications\n      operationId: communications.calls_UpdateParticipants\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n        - name: participant-id\n          in: path\n          description: 'key: participant-id of participant'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: participant\n      requestBody:\n        description: New navigation property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.participant'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/communications/calls/{call-id}/participants/{participant-id}/microsoft.graph.mute':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action mute\n      operationId: communications.calls.participants_mute\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n        - name: participant-id\n          in: path\n          description: 'key: participant-id of participant'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: participant\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                clientContext:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '200':\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.muteParticipantOperation'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  '/communications/calls/{call-id}/participants/microsoft.graph.invite':\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action invite\n      operationId: communications.calls.participants_invite\n      parameters:\n        - name: call-id\n          in: path\n          description: 'key: call-id of call'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: call\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                participants:\n                  type: array\n                  items:\n                    $ref: '#/components/schemas/microsoft.graph.invitationParticipantInfo'\n                clientContext:\n                  type: string\n                  nullable: true\n        required: true\n      responses:\n        '200':\n          description: Success\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.inviteParticipantsOperation'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  /communications/calls/microsoft.graph.logTeleconferenceDeviceQuality:\n    post:\n      tags:\n        - communications.Actions\n      summary: Invoke action logTeleconferenceDeviceQuality\n      operationId: communications.calls_logTeleconferenceDeviceQuality\n      requestBody:\n        description: Action parameters\n        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n                quality:\n                  $ref: '#/components/schemas/microsoft.graph.teleconferenceDeviceQuality'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: action\n  /communications/onlineMeetings:\n    get:\n      tags:\n        - communications.onlineMeeting\n      summary: Get onlineMeetings from communications\n      operationId: communications_ListOnlineMeetings\n      parameters:\n        - $ref: '#/components/parameters/top'\n        - $ref: '#/components/parameters/skip'\n        - $ref: '#/components/parameters/search'\n        - $ref: '#/components/parameters/filter'\n        - $ref: '#/components/parameters/count'\n        - name: $orderby\n          in: query\n          description: Order items by property values\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - id desc\n                - creationDateTime\n                - creationDateTime desc\n                - startDateTime\n                - startDateTime desc\n                - endDateTime\n                - endDateTime desc\n                - joinWebUrl\n                - joinWebUrl desc\n                - subject\n                - subject desc\n                - participants\n                - participants desc\n                - audioConferencing\n                - audioConferencing desc\n                - chatInfo\n                - chatInfo desc\n                - videoTeleconferenceId\n                - videoTeleconferenceId desc\n              type: string\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - creationDateTime\n                - startDateTime\n                - endDateTime\n                - joinWebUrl\n                - subject\n                - participants\n                - audioConferencing\n                - chatInfo\n                - videoTeleconferenceId\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                title: Collection of onlineMeeting\n                type: object\n                properties:\n                  value:\n                    type: array\n                    items:\n                      $ref: '#/components/schemas/microsoft.graph.onlineMeeting'\n                  '@odata.nextLink':\n                    type: string\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-pageable:\n        nextLinkName: '@odata.nextLink'\n        operationName: listMore\n      x-ms-docs-operation-type: operation\n    post:\n      tags:\n        - communications.onlineMeeting\n      summary: Create new navigation property to onlineMeetings for communications\n      operationId: communications_CreateOnlineMeetings\n      requestBody:\n        description: New navigation property\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.onlineMeeting'\n        required: true\n      responses:\n        '201':\n          description: Created navigation property.\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.onlineMeeting'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/communications/onlineMeetings/{onlineMeeting-id}':\n    get:\n      tags:\n        - communications.onlineMeeting\n      summary: Get onlineMeetings from communications\n      operationId: communications_GetOnlineMeetings\n      parameters:\n        - name: onlineMeeting-id\n          in: path\n          description: 'key: onlineMeeting-id of onlineMeeting'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: onlineMeeting\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - creationDateTime\n                - startDateTime\n                - endDateTime\n                - joinWebUrl\n                - subject\n                - participants\n                - audioConferencing\n                - chatInfo\n                - videoTeleconferenceId\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved navigation property\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.onlineMeeting'\n        default:\n          $ref: '#/components/responses/error'\n    patch:\n      tags:\n        - communications.onlineMeeting\n      summary: Update the navigation property onlineMeetings in communications\n      operationId: communications_UpdateOnlineMeetings\n      parameters:\n        - name: onlineMeeting-id\n          in: path\n          description: 'key: onlineMeeting-id of onlineMeeting'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: onlineMeeting\n      requestBody:\n        description: New navigation property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.onlineMeeting'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\ncomponents:\n  schemas:\n    microsoft.graph.cloudCommunications:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: cloudCommunications\n          type: object\n          properties:\n            calls:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.call'\n            onlineMeetings:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.onlineMeeting'\n      example:\n        id: string (identifier)\n        calls:\n          - '@odata.type': microsoft.graph.call\n        onlineMeetings:\n          - '@odata.type': microsoft.graph.onlineMeeting\n    microsoft.graph.call:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: call\n          type: object\n          properties:\n            state:\n              $ref: '#/components/schemas/microsoft.graph.callState'\n            mediaState:\n              $ref: '#/components/schemas/microsoft.graph.callMediaState'\n            resultInfo:\n              $ref: '#/components/schemas/microsoft.graph.resultInfo'\n            direction:\n              $ref: '#/components/schemas/microsoft.graph.callDirection'\n            subject:\n              type: string\n              description: The subject of the conversation.\n              nullable: true\n            callbackUri:\n              type: string\n              description: The callback URL on which callbacks will be delivered. Must be https.\n            callRoutes:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.callRoute'\n              description: The routing information on how the call was retargeted. Read-only.\n            source:\n              $ref: '#/components/schemas/microsoft.graph.participantInfo'\n            targets:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.invitationParticipantInfo'\n              description: The targets of the call. Required information for creating peer to peer call.\n            requestedModalities:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.modality'\n              description: 'The list of requested modalities. Possible values are: unknown, audio, video, videoBasedScreenSharing, data.'\n            mediaConfig:\n              $ref: '#/components/schemas/microsoft.graph.mediaConfig'\n            chatInfo:\n              $ref: '#/components/schemas/microsoft.graph.chatInfo'\n            callOptions:\n              $ref: '#/components/schemas/microsoft.graph.callOptions'\n            meetingInfo:\n              $ref: '#/components/schemas/microsoft.graph.meetingInfo'\n            tenantId:\n              type: string\n              nullable: true\n            myParticipantId:\n              type: string\n              description: Read-only.\n              nullable: true\n            toneInfo:\n              $ref: '#/components/schemas/microsoft.graph.toneInfo'\n            callChainId:\n              type: string\n              description: A unique identifier for all the participant calls in a conference or a unique identifier for two participant calls in a P2P call.  This needs to be copied over from Microsoft.Graph.Call.CallChainId.\n              nullable: true\n            incomingContext:\n              $ref: '#/components/schemas/microsoft.graph.incomingContext'\n            participants:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.participant'\n              description: Read-only. Nullable.\n            operations:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.commsOperation'\n              description: Read-only. Nullable.\n      example:\n        id: string (identifier)\n        state:\n          '@odata.type': microsoft.graph.callState\n        mediaState:\n          '@odata.type': microsoft.graph.callMediaState\n        resultInfo:\n          '@odata.type': microsoft.graph.resultInfo\n        direction:\n          '@odata.type': microsoft.graph.callDirection\n        subject: string\n        callbackUri: string\n        callRoutes:\n          - '@odata.type': microsoft.graph.callRoute\n        source:\n          '@odata.type': microsoft.graph.participantInfo\n        targets:\n          - '@odata.type': microsoft.graph.invitationParticipantInfo\n        requestedModalities:\n          - '@odata.type': microsoft.graph.modality\n        mediaConfig:\n          '@odata.type': microsoft.graph.mediaConfig\n        chatInfo:\n          '@odata.type': microsoft.graph.chatInfo\n        callOptions:\n          '@odata.type': microsoft.graph.callOptions\n        meetingInfo:\n          '@odata.type': microsoft.graph.meetingInfo\n        tenantId: string\n        myParticipantId: string\n        toneInfo:\n          '@odata.type': microsoft.graph.toneInfo\n        callChainId: string\n        incomingContext:\n          '@odata.type': microsoft.graph.incomingContext\n        participants:\n          - '@odata.type': microsoft.graph.participant\n        operations:\n          - '@odata.type': microsoft.graph.commsOperation\n    microsoft.graph.mediaConfig:\n      title: mediaConfig\n      type: object\n    microsoft.graph.modality:\n      title: modality\n      enum:\n        - audio\n        - video\n        - videoBasedScreenSharing\n        - data\n        - unknownFutureValue\n      type: string\n    microsoft.graph.screenSharingRole:\n      title: screenSharingRole\n      enum:\n        - viewer\n        - sharer\n      type: string\n    microsoft.graph.muteParticipantOperation:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        - title: muteParticipantOperation\n          type: object\n      example:\n        id: string (identifier)\n        status:\n          '@odata.type': microsoft.graph.operationStatus\n        clientContext: string\n        resultInfo:\n          '@odata.type': microsoft.graph.resultInfo\n    microsoft.graph.prompt:\n      title: prompt\n      type: object\n    microsoft.graph.playPromptOperation:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        - title: playPromptOperation\n          type: object\n      example:\n        id: string (identifier)\n        status:\n          '@odata.type': microsoft.graph.operationStatus\n        clientContext: string\n        resultInfo:\n          '@odata.type': microsoft.graph.resultInfo\n    microsoft.graph.recordOperation:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        - title: recordOperation\n          type: object\n          properties:\n            recordingLocation:\n              type: string\n              description: The location where the recording is located.\n              nullable: true\n            recordingAccessToken:\n              type: string\n              description: The access token required to retrieve the recording.\n              nullable: true\n      example:\n        id: string (identifier)\n        status:\n          '@odata.type': microsoft.graph.operationStatus\n        clientContext: string\n        resultInfo:\n          '@odata.type': microsoft.graph.resultInfo\n        recordingLocation: string\n        recordingAccessToken: string\n    microsoft.graph.invitationParticipantInfo:\n      title: invitationParticipantInfo\n      type: object\n      properties:\n        identity:\n          $ref: '#/components/schemas/microsoft.graph.identitySet'\n        replacesCallId:\n          type: string\n          description: Optional. The call which the target identity is currently a part of. This call will be dropped once the participant is added.\n          nullable: true\n      example:\n        identity:\n          '@odata.type': microsoft.graph.identitySet\n        replacesCallId: string\n    microsoft.graph.rejectReason:\n      title: rejectReason\n      enum:\n        - none\n        - busy\n        - forbidden\n        - unknownFutureValue\n      type: string\n    microsoft.graph.subscribeToToneOperation:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        - title: subscribeToToneOperation\n          type: object\n      example:\n        id: string (identifier)\n        status:\n          '@odata.type': microsoft.graph.operationStatus\n        clientContext: string\n        resultInfo:\n          '@odata.type': microsoft.graph.resultInfo\n    microsoft.graph.unmuteParticipantOperation:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        - title: unmuteParticipantOperation\n          type: object\n      example:\n        id: string (identifier)\n        status:\n          '@odata.type': microsoft.graph.operationStatus\n        clientContext: string\n        resultInfo:\n          '@odata.type': microsoft.graph.resultInfo\n    microsoft.graph.recordingStatus:\n      title: recordingStatus\n      enum:\n        - unknown\n        - notRecording\n        - recording\n        - failed\n        - unknownFutureValue\n      type: string\n    microsoft.graph.updateRecordingStatusOperation:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        - title: updateRecordingStatusOperation\n          type: object\n      example:\n        id: string (identifier)\n        status:\n          '@odata.type': microsoft.graph.operationStatus\n        clientContext: string\n        resultInfo:\n          '@odata.type': microsoft.graph.resultInfo\n    microsoft.graph.commsOperation:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: commsOperation\n          type: object\n          properties:\n            status:\n              $ref: '#/components/schemas/microsoft.graph.operationStatus'\n            clientContext:\n              type: string\n              description: Unique Client Context string. Max limit is 256 chars.\n              nullable: true\n            resultInfo:\n              $ref: '#/components/schemas/microsoft.graph.resultInfo'\n      example:\n        id: string (identifier)\n        status:\n          '@odata.type': microsoft.graph.operationStatus\n        clientContext: string\n        resultInfo:\n          '@odata.type': microsoft.graph.resultInfo\n    microsoft.graph.participant:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: participant\n          type: object\n          properties:\n            info:\n              $ref: '#/components/schemas/microsoft.graph.participantInfo'\n            recordingInfo:\n              $ref: '#/components/schemas/microsoft.graph.recordingInfo'\n            mediaStreams:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.mediaStream'\n              description: The list of media streams.\n            isMuted:\n              type: boolean\n              description: true if the participant is muted (client or server muted).\n            isInLobby:\n              type: boolean\n              description: true if the participant is in lobby.\n      example:\n        id: string (identifier)\n        info:\n          '@odata.type': microsoft.graph.participantInfo\n        recordingInfo:\n          '@odata.type': microsoft.graph.recordingInfo\n        mediaStreams:\n          - '@odata.type': microsoft.graph.mediaStream\n        isMuted: true\n        isInLobby: true\n    microsoft.graph.inviteParticipantsOperation:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.commsOperation'\n        - title: inviteParticipantsOperation\n          type: object\n          properties:\n            participants:\n              type: array\n              items:\n                $ref: '#/components/schemas/microsoft.graph.invitationParticipantInfo'\n              description: The participants to invite.\n      example:\n        id: string (identifier)\n        status:\n          '@odata.type': microsoft.graph.operationStatus\n        clientContext: string\n        resultInfo:\n          '@odata.type': microsoft.graph.resultInfo\n        participants:\n          - '@odata.type': microsoft.graph.invitationParticipantInfo\n    microsoft.graph.teleconferenceDeviceQuality:\n      title: teleconferenceDeviceQuality\n      type: object\n      properties:\n        callChainId:\n          pattern: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'\n          type: string\n          description: A unique identifier for all  the participant calls in a conference or a unique identifier for two participant calls in P2P call. This needs to be copied over from Microsoft.Graph.Call.CallChainId.\n          format: uuid\n        participantId:\n          pattern: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'\n          type: string\n          description: A unique identifier for a specific participant in a conference. The CVI partner needs to copy over Call.MyParticipantId to this property.\n          format: uuid\n        mediaLegId:\n          pattern: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'\n          type: string\n          description: A unique identifier for a specific media leg of a participant in a conference.  One participant can have multiple media leg identifiers if retargeting happens. CVI partner assigns this value.\n          format: uuid\n        deviceName:\n          type: string\n          description: 'The user media agent name, such as Cisco SX80.'\n        deviceDescription:\n          type: string\n          description: 'Any additional description, such as VTC Bldg 30/21.'\n        cloudServiceName:\n          type: string\n          description: 'The Azure deployed cloud service name, such as contoso.cloudapp.net.'\n          nullable: true\n        cloudServiceInstanceName:\n          type: string\n          description: 'The Azure deployed cloud service instance name, such as FrontEnd_IN_3.'\n          nullable: true\n        cloudServiceDeploymentId:\n          type: string\n          description: A unique deployment identifier assigned by Azure.\n          nullable: true\n        cloudServiceDeploymentEnvironment:\n          type: string\n          description: 'A geo-region where the service is deployed, such as ProdNoam.'\n          nullable: true\n        mediaQualityList:\n          type: array\n          items:\n            $ref: '#/components/schemas/microsoft.graph.teleconferenceDeviceMediaQuality'\n          description: 'The list of media qualities in a media session (call), such as audio quality, video quality, and/or screen sharing quality.'\n      example:\n        callChainId: string\n        participantId: string\n        mediaLegId: string\n        deviceName: string\n        deviceDescription: string\n        cloudServiceName: string\n        cloudServiceInstanceName: string\n        cloudServiceDeploymentId: string\n        cloudServiceDeploymentEnvironment: string\n        mediaQualityList:\n          - '@odata.type': microsoft.graph.teleconferenceDeviceMediaQuality\n    microsoft.graph.onlineMeeting:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: onlineMeeting\n          type: object\n          properties:\n            creationDateTime:\n              pattern: '^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$'\n              type: string\n              description: The meeting creation time in UTC. Read-only.\n              format: date-time\n              nullable: true\n            startDateTime:\n              pattern: '^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$'\n              type: string\n              description: The meeting start time in UTC.\n              format: date-time\n              nullable: true\n            endDateTime:\n              pattern: '^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$'\n              type: string\n              description: The meeting end time in UTC.\n              format: date-time\n              nullable: true\n            joinWebUrl:\n              type: string\n              description: The join URL of the online meeting. Read-only.\n              nullable: true\n            subject:\n              type: string\n              description: The subject of the online meeting.\n              nullable: true\n            participants:\n              $ref: '#/components/schemas/microsoft.graph.meetingParticipants'\n            audioConferencing:\n              $ref: '#/components/schemas/microsoft.graph.audioConferencing'\n            chatInfo:\n              $ref: '#/components/schemas/microsoft.graph.chatInfo'\n            videoTeleconferenceId:\n              type: string\n              description: The video teleconferencing ID. Read-only.\n              nullable: true\n      example:\n        id: string (identifier)\n        creationDateTime: string (timestamp)\n        startDateTime: string (timestamp)\n        endDateTime: string (timestamp)\n        joinWebUrl: string\n        subject: string\n        participants:\n          '@odata.type': microsoft.graph.meetingParticipants\n        audioConferencing:\n          '@odata.type': microsoft.graph.audioConferencing\n        chatInfo:\n          '@odata.type': microsoft.graph.chatInfo\n        videoTeleconferenceId: string\n    microsoft.graph.entity:\n      title: entity\n      type: object\n      properties:\n        id:\n          type: string\n          description: Read-only.\n      example:\n        id: string (identifier)\n    microsoft.graph.callState:\n      title: callState\n      enum:\n        - incoming\n        - establishing\n        - established\n        - hold\n        - transferring\n        - transferAccepted\n        - redirecting\n        - terminating\n        - terminated\n        - unknownFutureValue\n      type: string\n    microsoft.graph.callMediaState:\n      title: callMediaState\n      type: object\n      properties:\n        audio:\n          $ref: '#/components/schemas/microsoft.graph.mediaState'\n      example:\n        audio:\n          '@odata.type': microsoft.graph.mediaState\n    microsoft.graph.resultInfo:\n      title: resultInfo\n      type: object\n      properties:\n        code:\n          maximum: 2147483647\n          minimum: -2147483648\n          type: integer\n          description: The result code.\n          format: int32\n        subcode:\n          maximum: 2147483647\n          minimum: -2147483648\n          type: integer\n          description: The result sub-code.\n          format: int32\n        message:\n          type: string\n          description: The message.\n          nullable: true\n      example:\n        code: integer\n        subcode: integer\n        message: string\n    microsoft.graph.callDirection:\n      title: callDirection\n      enum:\n        - incoming\n        - outgoing\n      type: string\n    microsoft.graph.callRoute:\n      title: callRoute\n      type: object\n      properties:\n        routingType:\n          $ref: '#/components/schemas/microsoft.graph.routingType'\n        original:\n          $ref: '#/components/schemas/microsoft.graph.identitySet'\n        final:\n          $ref: '#/components/schemas/microsoft.graph.identitySet'\n      example:\n        routingType:\n          '@odata.type': microsoft.graph.routingType\n        original:\n          '@odata.type': microsoft.graph.identitySet\n        final:\n          '@odata.type': microsoft.graph.identitySet\n    microsoft.graph.participantInfo:\n      title: participantInfo\n      type: object\n      properties:\n        identity:\n          $ref: '#/components/schemas/microsoft.graph.identitySet'\n        endpointType:\n          $ref: '#/components/schemas/microsoft.graph.endpointType'\n        region:\n          type: string\n          description: 'The home region of the participant. This can be a country, a continent, or a larger geographic region. This does not change based on the participant''s current physical location. Read-only.'\n          nullable: true\n        languageId:\n          type: string\n          description: The language culture string. Read-only.\n          nullable: true\n        countryCode:\n          type: string\n          description: The ISO 3166-1 Alpha-2 country code of the participant's best estimated physical location at the start of the call. Read-only.\n          nullable: true\n      example:\n        identity:\n          '@odata.type': microsoft.graph.identitySet\n        endpointType:\n          '@odata.type': microsoft.graph.endpointType\n        region: string\n        languageId: string\n        countryCode: string\n    microsoft.graph.chatInfo:\n      title: chatInfo\n      type: object\n      properties:\n        threadId:\n          type: string\n          description: The unique identifier for a thread in Microsoft Teams.\n          nullable: true\n        messageId:\n          type: string\n          description: The unique identifier of a message in a Microsoft Teams channel.\n          nullable: true\n        replyChainMessageId:\n          type: string\n          description: The ID of the reply message.\n          nullable: true\n      example:\n        threadId: string\n        messageId: string\n        replyChainMessageId: string\n    microsoft.graph.callOptions:\n      title: callOptions\n      type: object\n    microsoft.graph.meetingInfo:\n      title: meetingInfo\n      type: object\n    microsoft.graph.toneInfo:\n      title: toneInfo\n      type: object\n      properties:\n        sequenceId:\n          type: integer\n          description: An incremental identifier used for ordering DTMF events.\n          format: int64\n        tone:\n          $ref: '#/components/schemas/microsoft.graph.tone'\n      example:\n        sequenceId: integer\n        tone:\n          '@odata.type': microsoft.graph.tone\n    microsoft.graph.incomingContext:\n      title: incomingContext\n      type: object\n      properties:\n        sourceParticipantId:\n          type: string\n          description: The ID of the participant that triggered the incoming call. Read-only.\n          nullable: true\n        observedParticipantId:\n          type: string\n          description: The ID of the participant that is under observation. Read-only.\n          nullable: true\n        onBehalfOf:\n          $ref: '#/components/schemas/microsoft.graph.identitySet'\n        transferor:\n          $ref: '#/components/schemas/microsoft.graph.identitySet'\n      example:\n        sourceParticipantId: string\n        observedParticipantId: string\n        onBehalfOf:\n          '@odata.type': microsoft.graph.identitySet\n        transferor:\n          '@odata.type': microsoft.graph.identitySet\n    microsoft.graph.identitySet:\n      title: identitySet\n      type: object\n      properties:\n        application:\n          $ref: '#/components/schemas/microsoft.graph.identity'\n        device:\n          $ref: '#/components/schemas/microsoft.graph.identity'\n        user:\n          $ref: '#/components/schemas/microsoft.graph.identity'\n      example:\n        application:\n          '@odata.type': microsoft.graph.identity\n        device:\n          '@odata.type': microsoft.graph.identity\n        user:\n          '@odata.type': microsoft.graph.identity\n    microsoft.graph.operationStatus:\n      title: operationStatus\n      enum:\n        - NotStarted\n        - Running\n        - Completed\n        - Failed\n      type: string\n    microsoft.graph.recordingInfo:\n      title: recordingInfo\n      type: object\n      properties:\n        recordingStatus:\n          $ref: '#/components/schemas/microsoft.graph.recordingStatus'\n        initiator:\n          $ref: '#/components/schemas/microsoft.graph.identitySet'\n      example:\n        recordingStatus:\n          '@odata.type': microsoft.graph.recordingStatus\n        initiator:\n          '@odata.type': microsoft.graph.identitySet\n    microsoft.graph.mediaStream:\n      title: mediaStream\n      type: object\n      properties:\n        mediaType:\n          $ref: '#/components/schemas/microsoft.graph.modality'\n        label:\n          type: string\n          description: The media stream label.\n          nullable: true\n        sourceId:\n          type: string\n          description: The source ID.\n        direction:\n          $ref: '#/components/schemas/microsoft.graph.mediaDirection'\n        serverMuted:\n          type: boolean\n          description: If the media is muted by the server.\n      example:\n        mediaType:\n          '@odata.type': microsoft.graph.modality\n        label: string\n        sourceId: string\n        direction:\n          '@odata.type': microsoft.graph.mediaDirection\n        serverMuted: true\n    microsoft.graph.teleconferenceDeviceMediaQuality:\n      title: teleconferenceDeviceMediaQuality\n      type: object\n      properties:\n        channelIndex:\n          maximum: 2147483647\n          minimum: -2147483648\n          type: integer\n          description: 'The channel index of media. Indexing begins with 1.  If a media session contains 3 video modalities, channel indexes will be 1, 2, and 3.'\n          format: int32\n        mediaDuration:\n          pattern: '^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$'\n          type: string\n          description: 'The total modality duration. If the media enabled and disabled multiple times, MediaDuration will the summation of all of the durations.'\n          format: duration\n          nullable: true\n        networkLinkSpeedInBytes:\n          type: integer\n          description: The network link speed in bytes\n          format: int64\n          nullable: true\n        localIPAddress:\n          type: string\n          description: the local IP address for the media session.\n          nullable: true\n        localPort:\n          maximum: 2147483647\n          minimum: -2147483648\n          type: integer\n          description: The local media port.\n          format: int32\n          nullable: true\n        remoteIPAddress:\n          type: string\n          description: The remote IP address for the media session.\n          nullable: true\n        remotePort:\n          maximum: 2147483647\n          minimum: -2147483648\n          type: integer\n          description: The remote media port.\n          format: int32\n          nullable: true\n        inboundPackets:\n          type: integer\n          description: The total number of the inbound packets.\n          format: int64\n          nullable: true\n        outboundPackets:\n          type: integer\n          description: The total number of the outbound packets.\n          format: int64\n          nullable: true\n        averageInboundPacketLossRateInPercentage:\n          type: number\n          description: 'The average inbound stream packet loss rate in percentage (0-100). For example, 0.01 means 0.01%.'\n          format: double\n          nullable: true\n        averageOutboundPacketLossRateInPercentage:\n          type: number\n          description: 'The average outbound stream packet loss rate in percentage (0-100). For example, 0.01 means 0.01%.'\n          format: double\n          nullable: true\n        maximumInboundPacketLossRateInPercentage:\n          type: number\n          description: 'The maximum inbound stream packet loss rate in percentage (0-100). For example, 0.01 means 0.01%.'\n          format: double\n          nullable: true\n        maximumOutboundPacketLossRateInPercentage:\n          type: number\n          description: 'The maximum outbound stream packet loss rate in percentage (0-100). For example, 0.01 means 0.01%.'\n          format: double\n          nullable: true\n        averageInboundRoundTripDelay:\n          pattern: '^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$'\n          type: string\n          description: The average inbound stream network round trip delay.\n          format: duration\n          nullable: true\n        averageOutboundRoundTripDelay:\n          pattern: '^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$'\n          type: string\n          description: The average outbound stream network round trip delay.\n          format: duration\n          nullable: true\n        maximumInboundRoundTripDelay:\n          pattern: '^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$'\n          type: string\n          description: The maximum inbound stream network round trip delay.\n          format: duration\n          nullable: true\n        maximumOutboundRoundTripDelay:\n          pattern: '^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$'\n          type: string\n          description: The maximum outbound stream network round trip delay.\n          format: duration\n          nullable: true\n        averageInboundJitter:\n          pattern: '^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$'\n          type: string\n          description: The average inbound stream network jitter.\n          format: duration\n          nullable: true\n        averageOutboundJitter:\n          pattern: '^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$'\n          type: string\n          description: The average outbound stream network jitter.\n          format: duration\n          nullable: true\n        maximumInboundJitter:\n          pattern: '^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$'\n          type: string\n          description: The maximum inbound stream network jitter.\n          format: duration\n          nullable: true\n        maximumOutboundJitter:\n          pattern: '^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$'\n          type: string\n          description: The maximum outbound stream network jitter.\n          format: duration\n          nullable: true\n      example:\n        channelIndex: integer\n        mediaDuration: string\n        networkLinkSpeedInBytes: integer\n        localIPAddress: string\n        localPort: integer\n        remoteIPAddress: string\n        remotePort: integer\n        inboundPackets: integer\n        outboundPackets: integer\n        averageInboundPacketLossRateInPercentage: double\n        averageOutboundPacketLossRateInPercentage: double\n        maximumInboundPacketLossRateInPercentage: double\n        maximumOutboundPacketLossRateInPercentage: double\n        averageInboundRoundTripDelay: string\n        averageOutboundRoundTripDelay: string\n        maximumInboundRoundTripDelay: string\n        maximumOutboundRoundTripDelay: string\n        averageInboundJitter: string\n        averageOutboundJitter: string\n        maximumInboundJitter: string\n        maximumOutboundJitter: string\n    microsoft.graph.meetingParticipants:\n      title: meetingParticipants\n      type: object\n      properties:\n        organizer:\n          $ref: '#/components/schemas/microsoft.graph.meetingParticipantInfo'\n        attendees:\n          type: array\n          items:\n            $ref: '#/components/schemas/microsoft.graph.meetingParticipantInfo'\n      example:\n        organizer:\n          '@odata.type': microsoft.graph.meetingParticipantInfo\n        attendees:\n          - '@odata.type': microsoft.graph.meetingParticipantInfo\n    microsoft.graph.audioConferencing:\n      title: audioConferencing\n      type: object\n      properties:\n        conferenceId:\n          type: string\n          nullable: true\n        tollNumber:\n          type: string\n          description: The toll number that connects to the Audio Conference Provider.\n          nullable: true\n        tollFreeNumber:\n          type: string\n          description: The toll-free number that connects to the Audio Conference Provider.\n          nullable: true\n        dialinUrl:\n          type: string\n          description: A URL to the externally-accessible web page that contains dial-in information.\n          nullable: true\n      example:\n        conferenceId: string\n        tollNumber: string\n        tollFreeNumber: string\n        dialinUrl: string\n    odata.error:\n      required:\n        - error\n      type: object\n      properties:\n        error:\n          $ref: '#/components/schemas/odata.error.main'\n    microsoft.graph.mediaState:\n      title: mediaState\n      enum:\n        - active\n        - inactive\n        - unknownFutureValue\n      type: string\n    microsoft.graph.routingType:\n      title: routingType\n      enum:\n        - forwarded\n        - lookup\n        - selfFork\n        - unknownFutureValue\n      type: string\n    microsoft.graph.endpointType:\n      title: endpointType\n      enum:\n        - default\n        - voicemail\n        - skypeForBusiness\n        - skypeForBusinessVoipPhone\n        - unknownFutureValue\n      type: string\n    microsoft.graph.tone:\n      title: tone\n      enum:\n        - tone0\n        - tone1\n        - tone2\n        - tone3\n        - tone4\n        - tone5\n        - tone6\n        - tone7\n        - tone8\n        - tone9\n        - star\n        - pound\n        - a\n        - b\n        - c\n        - d\n        - flash\n      type: string\n    microsoft.graph.identity:\n      title: identity\n      type: object\n      properties:\n        displayName:\n          type: string\n          description: 'The identity''s display name. Note that this may not always be available or up to date. For example, if a user changes their display name, the API may show the new value in a future response, but the items associated with the user won''t show up as having changed when using delta.'\n          nullable: true\n        id:\n          type: string\n          description: Unique identifier for the identity.\n          nullable: true\n      example:\n        displayName: string\n        id: string\n    microsoft.graph.mediaDirection:\n      title: mediaDirection\n      enum:\n        - inactive\n        - sendOnly\n        - receiveOnly\n        - sendReceive\n      type: string\n    microsoft.graph.meetingParticipantInfo:\n      title: meetingParticipantInfo\n      type: object\n      properties:\n        identity:\n          $ref: '#/components/schemas/microsoft.graph.identitySet'\n        upn:\n          type: string\n          description: User principal name of the participant.\n          nullable: true\n      example:\n        identity:\n          '@odata.type': microsoft.graph.identitySet\n        upn: string\n    odata.error.main:\n      required:\n        - code\n        - message\n      type: object\n      properties:\n        code:\n          type: string\n        message:\n          type: string\n        target:\n          type: string\n        details:\n          type: array\n          items:\n            $ref: '#/components/schemas/odata.error.detail'\n        innererror:\n          type: object\n          description: The structure of this object is service-specific\n    odata.error.detail:\n      required:\n        - code\n        - message\n      type: object\n      properties:\n        code:\n          type: string\n        message:\n          type: string\n        target:\n          type: string\n  responses:\n    error:\n      description: error\n      content:\n        application/json:\n          schema:\n            $ref: '#/components/schemas/odata.error'\n  parameters:\n    top:\n      name: $top\n      in: query\n      description: Show only the first n items\n      schema:\n        minimum: 0\n        type: integer\n      example: 50\n    skip:\n      name: $skip\n      in: query\n      description: Skip the first n items\n      schema:\n        minimum: 0\n        type: integer\n    search:\n      name: $search\n      in: query\n      description: Search items by search phrases\n      schema:\n        type: string\n    filter:\n      name: $filter\n      in: query\n      description: Filter items by property values\n      schema:\n        type: string\n    count:\n      name: $count\n      in: query\n      description: Include count of items\n      schema:\n        type: boolean\n  securitySchemes:\n    azureaadv2:\n      type: oauth2\n      flows:\n        authorizationCode:\n          authorizationUrl: https://login.microsoftonline.com/common/oauth2/v2.0/authorize\n          tokenUrl: https://login.microsoftonline.com/common/oauth2/v2.0/token\n          scopes: { }\nsecurity:\n  - azureaadv2: [ ]\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Resources/OpenApiDescriptions/MicrosoftGraph.PowershellSdk.Subscriptions.json",
    "content": "{\n  \"openapi\": \"3.0.1\",\n  \"info\": {\n    \"title\": \"Subscriptions\",\n    \"version\": \"v1.0\"\n  },\n  \"servers\": [\n    {\n      \"url\": \"https://graph.microsoft.com/v1.0/\",\n      \"description\": \"Core\"\n    }\n  ],\n  \"paths\": {\n    \"/subscriptions\": {\n      \"get\": {\n        \"tags\": [\n          \"subscriptions.subscription\"\n        ],\n        \"summary\": \"Get entities from subscriptions\",\n        \"operationId\": \"subscriptions.subscription_ListSubscription\",\n        \"parameters\": [\n          {\n            \"$ref\": \"#/components/parameters/top\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/skip\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/search\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/filter\"\n          },\n          {\n            \"$ref\": \"#/components/parameters/count\"\n          },\n          {\n            \"name\": \"$orderby\",\n            \"in\": \"query\",\n            \"description\": \"Order items by property values\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"id desc\",\n                  \"resource\",\n                  \"resource desc\",\n                  \"changeType\",\n                  \"changeType desc\",\n                  \"clientState\",\n                  \"clientState desc\",\n                  \"notificationUrl\",\n                  \"notificationUrl desc\",\n                  \"expirationDateTime\",\n                  \"expirationDateTime desc\",\n                  \"applicationId\",\n                  \"applicationId desc\",\n                  \"creatorId\",\n                  \"creatorId desc\",\n                  \"latestSupportedTlsVersion\",\n                  \"latestSupportedTlsVersion desc\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"resource\",\n                  \"changeType\",\n                  \"clientState\",\n                  \"notificationUrl\",\n                  \"expirationDateTime\",\n                  \"applicationId\",\n                  \"creatorId\",\n                  \"latestSupportedTlsVersion\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved entities\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"title\": \"Collection of subscription\",\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"value\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"$ref\": \"#/components/schemas/microsoft.graph.subscription\"\n                      }\n                    },\n                    \"@odata.nextLink\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-pageable\": {\n          \"nextLinkName\": \"@odata.nextLink\",\n          \"operationName\": \"listMore\"\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"post\": {\n        \"tags\": [\n          \"subscriptions.subscription\"\n        ],\n        \"summary\": \"Add new entity to subscriptions\",\n        \"operationId\": \"subscriptions.subscription_CreateSubscription\",\n        \"requestBody\": {\n          \"description\": \"New entity\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.subscription\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created entity\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.subscription\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    },\n    \"/subscriptions/{subscription-id}\": {\n      \"get\": {\n        \"tags\": [\n          \"subscriptions.subscription\"\n        ],\n        \"summary\": \"Get entity from subscriptions by key\",\n        \"operationId\": \"subscriptions.subscription_GetSubscription\",\n        \"parameters\": [\n          {\n            \"name\": \"subscription-id\",\n            \"in\": \"path\",\n            \"description\": \"key: subscription-id of subscription\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"subscription\"\n          },\n          {\n            \"name\": \"$select\",\n            \"in\": \"query\",\n            \"description\": \"Select properties to be returned\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"id\",\n                  \"resource\",\n                  \"changeType\",\n                  \"clientState\",\n                  \"notificationUrl\",\n                  \"expirationDateTime\",\n                  \"applicationId\",\n                  \"creatorId\",\n                  \"latestSupportedTlsVersion\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          },\n          {\n            \"name\": \"$expand\",\n            \"in\": \"query\",\n            \"description\": \"Expand related entities\",\n            \"style\": \"form\",\n            \"explode\": false,\n            \"schema\": {\n              \"uniqueItems\": true,\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"*\"\n                ],\n                \"type\": \"string\"\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Retrieved entity\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/microsoft.graph.subscription\"\n                }\n              }\n            }\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"patch\": {\n        \"tags\": [\n          \"subscriptions.subscription\"\n        ],\n        \"summary\": \"Update entity in subscriptions\",\n        \"operationId\": \"subscriptions.subscription_UpdateSubscription\",\n        \"parameters\": [\n          {\n            \"name\": \"subscription-id\",\n            \"in\": \"path\",\n            \"description\": \"key: subscription-id of subscription\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"subscription\"\n          }\n        ],\n        \"requestBody\": {\n          \"description\": \"New property values\",\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/microsoft.graph.subscription\"\n              }\n            }\n          },\n          \"required\": true\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      },\n      \"delete\": {\n        \"tags\": [\n          \"subscriptions.subscription\"\n        ],\n        \"summary\": \"Delete entity from subscriptions\",\n        \"operationId\": \"subscriptions.subscription_DeleteSubscription\",\n        \"parameters\": [\n          {\n            \"name\": \"subscription-id\",\n            \"in\": \"path\",\n            \"description\": \"key: subscription-id of subscription\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"x-ms-docs-key-type\": \"subscription\"\n          },\n          {\n            \"name\": \"If-Match\",\n            \"in\": \"header\",\n            \"description\": \"ETag\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Success\"\n          },\n          \"default\": {\n            \"$ref\": \"#/components/responses/error\"\n          }\n        },\n        \"x-ms-docs-operation-type\": \"operation\"\n      }\n    }\n  },\n  \"components\": {\n    \"schemas\": {\n      \"microsoft.graph.subscription\": {\n        \"allOf\": [\n          {\n            \"$ref\": \"#/components/schemas/microsoft.graph.entity\"\n          },\n          {\n            \"title\": \"subscription\",\n            \"type\": \"object\",\n            \"properties\": {\n              \"resource\": {\n                \"type\": \"string\",\n                \"description\": \"Required. Specifies the resource that will be monitored for changes. Do not include the base URL (https://graph.microsoft.com/v1.0/). See the possible resource path values for each supported resource.\"\n              },\n              \"changeType\": {\n                \"type\": \"string\",\n                \"description\": \"Required. Indicates the type of change in the subscribed resource that will raise a change notification. The supported values are: created, updated, deleted. Multiple values can be combined using a comma-separated list.Note: Drive root item and list change notifications support only the updated changeType. User and group change notifications support updated and deleted changeType.\"\n              },\n              \"clientState\": {\n                \"type\": \"string\",\n                \"description\": \"Optional. Specifies the value of the clientState property sent by the service in each change notification. The maximum length is 128 characters. The client can check that the change notification came from the service by comparing the value of the clientState property sent with the subscription with the value of the clientState property received with each change notification.\",\n                \"nullable\": true\n              },\n              \"notificationUrl\": {\n                \"type\": \"string\",\n                \"description\": \"Required. The URL of the endpoint that will receive the change notifications. This URL must make use of the HTTPS protocol.\"\n              },\n              \"expirationDateTime\": {\n                \"pattern\": \"^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$\",\n                \"type\": \"string\",\n                \"description\": \"Required. Specifies the date and time when the webhook subscription expires. The time is in UTC, and can be an amount of time from subscription creation that varies for the resource subscribed to.  See the table below for maximum supported subscription length of time.\",\n                \"format\": \"date-time\"\n              },\n              \"applicationId\": {\n                \"type\": \"string\",\n                \"description\": \"Identifier of the application used to create the subscription. Read-only.\",\n                \"nullable\": true\n              },\n              \"creatorId\": {\n                \"type\": \"string\",\n                \"description\": \"Identifier of the user or service principal that created the subscription. If the app used delegated permissions to create the subscription, this field contains the id of the signed-in user the app called on behalf of. If the app used application permissions, this field contains the id of the service principal corresponding to the app. Read-only.\",\n                \"nullable\": true\n              },\n              \"latestSupportedTlsVersion\": {\n                \"type\": \"string\",\n                \"description\": \"Specifies the latest version of Transport Layer Security (TLS) that the notification endpoint, specified by notificationUrl, supports. The possible values are: v1_0, v1_1, v1_2, v1_3. For subscribers whose notification endpoint supports a version lower than the currently recommended version (TLS 1.2), specifying this property by a set timeline allows them to temporarily use their deprecated version of TLS before completing their upgrade to TLS 1.2. For these subscribers, not setting this property per the timeline would result in subscription operations failing. For subscribers whose notification endpoint already supports TLS 1.2, setting this property is optional. In such cases, Microsoft Graph defaults the property to v1_2.\",\n                \"nullable\": true\n              }\n            }\n          }\n        ],\n        \"example\": {\n          \"id\": \"string (identifier)\",\n          \"resource\": \"string\",\n          \"changeType\": \"string\",\n          \"clientState\": \"string\",\n          \"notificationUrl\": \"string\",\n          \"expirationDateTime\": \"string (timestamp)\",\n          \"applicationId\": \"string\",\n          \"creatorId\": \"string\",\n          \"latestSupportedTlsVersion\": \"string\"\n        }\n      },\n      \"microsoft.graph.entity\": {\n        \"title\": \"entity\",\n        \"type\": \"object\",\n        \"properties\": {\n          \"id\": {\n            \"type\": \"string\",\n            \"description\": \"Read-only.\"\n          }\n        },\n        \"example\": {\n          \"id\": \"string (identifier)\"\n        }\n      },\n      \"odata.error\": {\n        \"required\": [\n          \"error\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"error\": {\n            \"$ref\": \"#/components/schemas/odata.error.main\"\n          }\n        }\n      },\n      \"odata.error.main\": {\n        \"required\": [\n          \"code\",\n          \"message\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"code\": {\n            \"type\": \"string\"\n          },\n          \"message\": {\n            \"type\": \"string\"\n          },\n          \"target\": {\n            \"type\": \"string\"\n          },\n          \"details\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"$ref\": \"#/components/schemas/odata.error.detail\"\n            }\n          },\n          \"innererror\": {\n            \"type\": \"object\",\n            \"description\": \"The structure of this object is service-specific\"\n          }\n        }\n      },\n      \"odata.error.detail\": {\n        \"required\": [\n          \"code\",\n          \"message\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"code\": {\n            \"type\": \"string\"\n          },\n          \"message\": {\n            \"type\": \"string\"\n          },\n          \"target\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"responses\": {\n      \"error\": {\n        \"description\": \"error\",\n        \"content\": {\n          \"application/json\": {\n            \"schema\": {\n              \"$ref\": \"#/components/schemas/odata.error\"\n            }\n          }\n        }\n      }\n    },\n    \"parameters\": {\n      \"top\": {\n        \"name\": \"$top\",\n        \"in\": \"query\",\n        \"description\": \"Show only the first n items\",\n        \"schema\": {\n          \"minimum\": 0,\n          \"type\": \"integer\"\n        },\n        \"example\": 50\n      },\n      \"skip\": {\n        \"name\": \"$skip\",\n        \"in\": \"query\",\n        \"description\": \"Skip the first n items\",\n        \"schema\": {\n          \"minimum\": 0,\n          \"type\": \"integer\"\n        }\n      },\n      \"search\": {\n        \"name\": \"$search\",\n        \"in\": \"query\",\n        \"description\": \"Search items by search phrases\",\n        \"schema\": {\n          \"type\": \"string\"\n        }\n      },\n      \"filter\": {\n        \"name\": \"$filter\",\n        \"in\": \"query\",\n        \"description\": \"Filter items by property values\",\n        \"schema\": {\n          \"type\": \"string\"\n        }\n      },\n      \"count\": {\n        \"name\": \"$count\",\n        \"in\": \"query\",\n        \"description\": \"Include count of items\",\n        \"schema\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"securitySchemes\": {\n      \"azureaadv2\": {\n        \"type\": \"oauth2\",\n        \"flows\": {\n          \"authorizationCode\": {\n            \"authorizationUrl\": \"https://login.microsoftonline.com/common/oauth2/v2.0/authorize\",\n            \"tokenUrl\": \"https://login.microsoftonline.com/common/oauth2/v2.0/token\",\n            \"scopes\": {}\n          }\n        }\n      }\n    }\n  },\n  \"security\": [\n    {\n      \"azureaadv2\": []\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Resources/OpenApiDescriptions/MicrosoftGraph.PowershellSdk.Subscriptions.yml",
    "content": "# Originally from https://github.com/microsoftgraph/msgraph-sdk-powershell/tree/dev/openApiDocs/v1.0\n\nopenapi: 3.0.1\ninfo:\n  title: Subscriptions\n  version: v1.0\nservers:\n  - url: https://graph.microsoft.com/v1.0/\n    description: Core\npaths:\n  /subscriptions:\n    get:\n      tags:\n        - subscriptions.subscription\n      summary: Get entities from subscriptions\n      operationId: subscriptions.subscription_ListSubscription\n      parameters:\n        - $ref: '#/components/parameters/top'\n        - $ref: '#/components/parameters/skip'\n        - $ref: '#/components/parameters/search'\n        - $ref: '#/components/parameters/filter'\n        - $ref: '#/components/parameters/count'\n        - name: $orderby\n          in: query\n          description: Order items by property values\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - id desc\n                - resource\n                - resource desc\n                - changeType\n                - changeType desc\n                - clientState\n                - clientState desc\n                - notificationUrl\n                - notificationUrl desc\n                - expirationDateTime\n                - expirationDateTime desc\n                - applicationId\n                - applicationId desc\n                - creatorId\n                - creatorId desc\n                - latestSupportedTlsVersion\n                - latestSupportedTlsVersion desc\n              type: string\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - resource\n                - changeType\n                - clientState\n                - notificationUrl\n                - expirationDateTime\n                - applicationId\n                - creatorId\n                - latestSupportedTlsVersion\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved entities\n          content:\n            application/json:\n              schema:\n                title: Collection of subscription\n                type: object\n                properties:\n                  value:\n                    type: array\n                    items:\n                      $ref: '#/components/schemas/microsoft.graph.subscription'\n                  '@odata.nextLink':\n                    type: string\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-pageable:\n        nextLinkName: '@odata.nextLink'\n        operationName: listMore\n      x-ms-docs-operation-type: operation\n    post:\n      tags:\n        - subscriptions.subscription\n      summary: Add new entity to subscriptions\n      operationId: subscriptions.subscription_CreateSubscription\n      requestBody:\n        description: New entity\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.subscription'\n        required: true\n      responses:\n        '201':\n          description: Created entity\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.subscription'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n  '/subscriptions/{subscription-id}':\n    get:\n      tags:\n        - subscriptions.subscription\n      summary: Get entity from subscriptions by key\n      operationId: subscriptions.subscription_GetSubscription\n      parameters:\n        - name: subscription-id\n          in: path\n          description: 'key: subscription-id of subscription'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: subscription\n        - name: $select\n          in: query\n          description: Select properties to be returned\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - id\n                - resource\n                - changeType\n                - clientState\n                - notificationUrl\n                - expirationDateTime\n                - applicationId\n                - creatorId\n                - latestSupportedTlsVersion\n              type: string\n        - name: $expand\n          in: query\n          description: Expand related entities\n          style: form\n          explode: false\n          schema:\n            uniqueItems: true\n            type: array\n            items:\n              enum:\n                - '*'\n              type: string\n      responses:\n        '200':\n          description: Retrieved entity\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/microsoft.graph.subscription'\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n    patch:\n      tags:\n        - subscriptions.subscription\n      summary: Update entity in subscriptions\n      operationId: subscriptions.subscription_UpdateSubscription\n      parameters:\n        - name: subscription-id\n          in: path\n          description: 'key: subscription-id of subscription'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: subscription\n      requestBody:\n        description: New property values\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/microsoft.graph.subscription'\n        required: true\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\n    delete:\n      tags:\n        - subscriptions.subscription\n      summary: Delete entity from subscriptions\n      operationId: subscriptions.subscription_DeleteSubscription\n      parameters:\n        - name: subscription-id\n          in: path\n          description: 'key: subscription-id of subscription'\n          required: true\n          schema:\n            type: string\n          x-ms-docs-key-type: subscription\n        - name: If-Match\n          in: header\n          description: ETag\n          schema:\n            type: string\n      responses:\n        '204':\n          description: Success\n        default:\n          $ref: '#/components/responses/error'\n      x-ms-docs-operation-type: operation\ncomponents:\n  schemas:\n    microsoft.graph.subscription:\n      allOf:\n        - $ref: '#/components/schemas/microsoft.graph.entity'\n        - title: subscription\n          type: object\n          properties:\n            resource:\n              type: string\n              description: Required. Specifies the resource that will be monitored for changes. Do not include the base URL (https://graph.microsoft.com/v1.0/). See the possible resource path values for each supported resource.\n            changeType:\n              type: string\n              description: 'Required. Indicates the type of change in the subscribed resource that will raise a change notification. The supported values are: created, updated, deleted. Multiple values can be combined using a comma-separated list.Note: Drive root item and list change notifications support only the updated changeType. User and group change notifications support updated and deleted changeType.'\n            clientState:\n              type: string\n              description: Optional. Specifies the value of the clientState property sent by the service in each change notification. The maximum length is 128 characters. The client can check that the change notification came from the service by comparing the value of the clientState property sent with the subscription with the value of the clientState property received with each change notification.\n              nullable: true\n            notificationUrl:\n              type: string\n              description: Required. The URL of the endpoint that will receive the change notifications. This URL must make use of the HTTPS protocol.\n            expirationDateTime:\n              pattern: '^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$'\n              type: string\n              description: 'Required. Specifies the date and time when the webhook subscription expires. The time is in UTC, and can be an amount of time from subscription creation that varies for the resource subscribed to.  See the table below for maximum supported subscription length of time.'\n              format: date-time\n            applicationId:\n              type: string\n              description: Identifier of the application used to create the subscription. Read-only.\n              nullable: true\n            creatorId:\n              type: string\n              description: 'Identifier of the user or service principal that created the subscription. If the app used delegated permissions to create the subscription, this field contains the id of the signed-in user the app called on behalf of. If the app used application permissions, this field contains the id of the service principal corresponding to the app. Read-only.'\n              nullable: true\n            latestSupportedTlsVersion:\n              type: string\n              description: 'Specifies the latest version of Transport Layer Security (TLS) that the notification endpoint, specified by notificationUrl, supports. The possible values are: v1_0, v1_1, v1_2, v1_3. For subscribers whose notification endpoint supports a version lower than the currently recommended version (TLS 1.2), specifying this property by a set timeline allows them to temporarily use their deprecated version of TLS before completing their upgrade to TLS 1.2. For these subscribers, not setting this property per the timeline would result in subscription operations failing. For subscribers whose notification endpoint already supports TLS 1.2, setting this property is optional. In such cases, Microsoft Graph defaults the property to v1_2.'\n              nullable: true\n      example:\n        id: string (identifier)\n        resource: string\n        changeType: string\n        clientState: string\n        notificationUrl: string\n        expirationDateTime: string (timestamp)\n        applicationId: string\n        creatorId: string\n        latestSupportedTlsVersion: string\n    microsoft.graph.entity:\n      title: entity\n      type: object\n      properties:\n        id:\n          type: string\n          description: Read-only.\n      example:\n        id: string (identifier)\n    odata.error:\n      required:\n        - error\n      type: object\n      properties:\n        error:\n          $ref: '#/components/schemas/odata.error.main'\n    odata.error.main:\n      required:\n        - code\n        - message\n      type: object\n      properties:\n        code:\n          type: string\n        message:\n          type: string\n        target:\n          type: string\n        details:\n          type: array\n          items:\n            $ref: '#/components/schemas/odata.error.detail'\n        innererror:\n          type: object\n          description: The structure of this object is service-specific\n    odata.error.detail:\n      required:\n        - code\n        - message\n      type: object\n      properties:\n        code:\n          type: string\n        message:\n          type: string\n        target:\n          type: string\n  responses:\n    error:\n      description: error\n      content:\n        application/json:\n          schema:\n            $ref: '#/components/schemas/odata.error'\n  parameters:\n    top:\n      name: $top\n      in: query\n      description: Show only the first n items\n      schema:\n        minimum: 0\n        type: integer\n      example: 50\n    skip:\n      name: $skip\n      in: query\n      description: Skip the first n items\n      schema:\n        minimum: 0\n        type: integer\n    search:\n      name: $search\n      in: query\n      description: Search items by search phrases\n      schema:\n        type: string\n    filter:\n      name: $filter\n      in: query\n      description: Filter items by property values\n      schema:\n        type: string\n    count:\n      name: $count\n      in: query\n      description: Include count of items\n      schema:\n        type: boolean\n  securitySchemes:\n    azureaadv2:\n      type: oauth2\n      flows:\n        authorizationCode:\n          authorizationUrl: https://login.microsoftonline.com/common/oauth2/v2.0/authorize\n          tokenUrl: https://login.microsoftonline.com/common/oauth2/v2.0/token\n          scopes: { }\nsecurity:\n  - azureaadv2: [ ]\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Resources/OpenApiDescriptions/xkcd.json",
    "content": "{\n  \"openapi\": \"3.0.0\",\n  \"servers\": [\n    {\n      \"url\": \"http://xkcd.com/\"\n    }\n  ],\n  \"info\": {\n    \"description\": \"Webcomic of romance, sarcasm, math, and language.\",\n    \"title\": \"XKCD\",\n    \"version\": \"1.0.0\",\n    \"x-apisguru-categories\": [\n      \"media\"\n    ],\n    \"x-logo\": {\n      \"url\": \"https://api.apis.guru/v2/cache/logo/http_imgs.xkcd.com_static_terrible_small_logo.png\"\n    },\n    \"x-origin\": [\n      {\n        \"format\": \"openapi\",\n        \"url\": \"https://raw.githubusercontent.com/APIs-guru/unofficial_openapi_specs/master/xkcd.com/1.0.0/openapi.yaml\",\n        \"version\": \"3.0\"\n      }\n    ],\n    \"x-preferred\": true,\n    \"x-providerName\": \"xkcd.com\",\n    \"x-tags\": [\n      \"humor\",\n      \"comics\"\n    ],\n    \"x-unofficialSpec\": true\n  },\n  \"externalDocs\": {\n    \"url\": \"https://xkcd.com/json.html\"\n  },\n  \"paths\": {\n    \"/info.0.json\": {\n      \"get\": {\n        \"description\": \"Fetch current comic and metadata.\\n\",\n        \"responses\": {\n          \"200\": {\n            \"content\": {\n              \"*/*\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/comic\"\n                }\n              }\n            },\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/{comicId}/info.0.json\": {\n      \"get\": {\n        \"description\": \"Fetch comics and metadata  by comic id.\\n\",\n        \"parameters\": [\n          {\n            \"in\": \"path\",\n            \"name\": \"comicId\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"number\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"content\": {\n              \"*/*\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/comic\"\n                }\n              }\n            },\n            \"description\": \"OK\"\n          }\n        }\n      }\n    }\n  },\n  \"components\": {\n    \"schemas\": {\n      \"comic\": {\n        \"properties\": {\n          \"alt\": {\n            \"type\": \"string\"\n          },\n          \"day\": {\n            \"type\": \"string\"\n          },\n          \"img\": {\n            \"type\": \"string\"\n          },\n          \"link\": {\n            \"type\": \"string\"\n          },\n          \"month\": {\n            \"type\": \"string\"\n          },\n          \"news\": {\n            \"type\": \"string\"\n          },\n          \"num\": {\n            \"type\": \"number\"\n          },\n          \"safe_title\": {\n            \"type\": \"string\"\n          },\n          \"title\": {\n            \"type\": \"string\"\n          },\n          \"transcript\": {\n            \"type\": \"string\"\n          },\n          \"year\": {\n            \"type\": \"string\"\n          }\n        },\n        \"type\": \"object\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Resources/OpenApiDescriptions/xkcd.yml",
    "content": "# Originally from https://api.apis.guru/v2/specs/xkcd.com/1.0.0/openapi.yaml\n\nopenapi: 3.0.0\nservers:\n  - url: 'http://xkcd.com/'\ninfo:\n  description: 'Webcomic of romance, sarcasm, math, and language.'\n  title: XKCD\n  version: 1.0.0\n  x-apisguru-categories:\n    - media\n  x-logo:\n    url: 'https://api.apis.guru/v2/cache/logo/http_imgs.xkcd.com_static_terrible_small_logo.png'\n  x-origin:\n    - format: openapi\n      url: 'https://raw.githubusercontent.com/APIs-guru/unofficial_openapi_specs/master/xkcd.com/1.0.0/openapi.yaml'\n      version: '3.0'\n  x-preferred: true\n  x-providerName: xkcd.com\n  x-tags:\n    - humor\n    - comics\n  x-unofficialSpec: true\nexternalDocs:\n  url: 'https://xkcd.com/json.html'\npaths:\n  /info.0.json:\n    get:\n      description: |\n        Fetch current comic and metadata.\n      responses:\n        '200':\n          content:\n            '*/*':\n              schema:\n                $ref: '#/components/schemas/comic'\n          description: OK\n  '/{comicId}/info.0.json':\n    get:\n      description: |\n        Fetch comics and metadata  by comic id.\n      parameters:\n        - in: path\n          name: comicId\n          required: true\n          schema:\n            type: number\n      responses:\n        '200':\n          content:\n            '*/*':\n              schema:\n                $ref: '#/components/schemas/comic'\n          description: OK\ncomponents:\n  schemas:\n    comic:\n      properties:\n        alt:\n          type: string\n        day:\n          type: string\n        img:\n          type: string\n        link:\n          type: string\n        month:\n          type: string\n        news:\n          type: string\n        num:\n          type: number\n        safe_title:\n          type: string\n        title:\n          type: string\n        transcript:\n          type: string\n        year:\n          type: string\n      type: object\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Suggestions/HeaderCompletionTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\nusing System.Net.Http;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.OpenApi;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Suggestions;\nusing Microsoft.HttpRepl.UserProfile;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Suggestions\n{\n    public class HeaderCompletionTests\n    {\n        [Fact]\n        public void GetCompletions_NullExistingHeaders_ProperResults()\n        {\n            IEnumerable<string> result = HeaderCompletion.GetCompletions(null, \"U\");\n\n            Assert.Equal(3, result.Count());\n            Assert.Contains(\"Upgrade\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"Upgrade-Insecure-Requests\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"User-Agent\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetCompletions_ExistingHeader_ProperResults()\n        {\n            IReadOnlyCollection<string> existingHeaders = new Collection<string>() { \"User-Agent\" };\n\n            IEnumerable<string> result = HeaderCompletion.GetCompletions(existingHeaders, \"U\");\n\n            Assert.Equal(2, result.Count());\n            Assert.Contains(\"Upgrade\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"Upgrade-Insecure-Requests\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetCompletions_NotAnExistingHeader_ProperResults()\n        {\n            IReadOnlyCollection<string> existingHeaders = new Collection<string>() { \"Content-Type\" };\n\n            IEnumerable<string> result = HeaderCompletion.GetCompletions(existingHeaders, \"U\");\n\n            Assert.Equal(3, result.Count());\n            Assert.Contains(\"Upgrade\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"Upgrade-Insecure-Requests\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"User-Agent\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetCompletions_NoResults_ReturnsEmpty()\n        {\n            IEnumerable<string> result = HeaderCompletion.GetCompletions(null, \"Not-A-Real-Header\");\n\n            Assert.Empty(result);\n        }\n\n        [Theory]\n        [InlineData(\"Accept\")]\n        [InlineData(\"Content-Length\")]\n        [InlineData(\"X-Requested-With\")]\n        public void GetValueCompletions_NoHeaderMatch_ReturnsNull(string header)\n        {\n            HttpState httpState = SetupHttpState();\n\n            IEnumerable<string> result = HeaderCompletion.GetValueCompletions(method: null, path: null, header, prefix: null, httpState);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void GetValueCompletions_NoMatch_ReturnsNull()\n        {\n            HttpState httpState = SetupHttpState();\n\n            IEnumerable<string> result = HeaderCompletion.GetValueCompletions(method: \"GET\", path: \"\", header: \"Content-Type\", \"\", httpState);\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void GetValueCompletions_OneMatch_ReturnsMatch()\n        {\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            RequestInfo requestInfo = new RequestInfo();\n            requestInfo.SetRequestBody(\"GET\", \"application/json\", \"\");\n            requestInfo.SetRequestBody(\"PUT\", \"application/xml\", \"\");\n            directoryStructure.RequestInfo = requestInfo;\n\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = new Uri(\"https://localhost/\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = directoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n\n            IEnumerable<string> result = HeaderCompletion.GetValueCompletions(method: \"GET\", path: \"\", header: \"Content-Type\", \"\", httpState);\n\n            Assert.Single(result);\n            Assert.Contains(\"application/json\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetValueCompletions_MultipleMatches_ReturnsCorrectMatches()\n        {\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            RequestInfo requestInfo = new RequestInfo();\n            requestInfo.SetRequestBody(\"GET\", \"application/json\", \"\");\n            requestInfo.SetRequestBody(\"GET\", \"text/plain\", \"\");\n            requestInfo.SetRequestBody(\"PUT\", \"application/xml\", \"\");\n            directoryStructure.RequestInfo = requestInfo;\n\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = new Uri(\"https://localhost/\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = directoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n\n            IEnumerable<string> result = HeaderCompletion.GetValueCompletions(method: \"GET\", path: \"\", header: \"Content-Type\", \"\", httpState);\n\n            Assert.Equal(2, result.Count());\n            Assert.Contains(\"application/json\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"text/plain\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetValueCompletions_NoMethod_ReturnsAll()\n        {\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            RequestInfo requestInfo = new RequestInfo();\n            requestInfo.SetRequestBody(\"GET\", \"application/json\", \"\");\n            requestInfo.SetRequestBody(\"GET\", \"text/plain\", \"\");\n            requestInfo.SetRequestBody(\"PUT\", \"application/xml\", \"\");\n            directoryStructure.RequestInfo = requestInfo;\n\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = new Uri(\"https://localhost/\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = directoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n\n            IEnumerable<string> result = HeaderCompletion.GetValueCompletions(method: null, path: \"\", header: \"Content-Type\", \"\", httpState);\n\n            Assert.Equal(3, result.Count());\n            Assert.Contains(\"application/json\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"text/plain\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"application/xml\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetValueCompletions_WithPrefix_ReturnsMatch()\n        {\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            RequestInfo requestInfo = new RequestInfo();\n            requestInfo.SetRequestBody(\"GET\", \"application/json\", \"\");\n            requestInfo.SetRequestBody(\"GET\", \"text/plain\", \"\");\n            requestInfo.SetRequestBody(\"PUT\", \"application/xml\", \"\");\n            directoryStructure.RequestInfo = requestInfo;\n\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = new Uri(\"https://localhost/\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = directoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n\n            IEnumerable<string> result = HeaderCompletion.GetValueCompletions(method: \"GET\", path: \"\", header: \"Content-Type\", \"a\", httpState);\n\n            Assert.Single(result);\n            Assert.Contains(\"application/json\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetValueCompletions_EmptyContentType_Skips()\n        {\n            DirectoryStructure directoryStructure = new DirectoryStructure(null);\n            RequestInfo requestInfo = new RequestInfo();\n            requestInfo.SetRequestBody(\"GET\", \"application/json\", \"\");\n            requestInfo.SetRequestBody(\"GET\", \"\", \"\");\n            directoryStructure.RequestInfo = requestInfo;\n\n            HttpState httpState = SetupHttpState();\n            httpState.BaseAddress = new Uri(\"https://localhost/\");\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = directoryStructure;\n            httpState.ApiDefinition = apiDefinition;\n\n            IEnumerable<string> result = HeaderCompletion.GetValueCompletions(method: \"GET\", path: \"\", header: \"Content-Type\", \"\", httpState);\n\n            Assert.Single(result);\n            Assert.Contains(\"application/json\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        private static HttpState SetupHttpState()\n        {\n            IFileSystem fileSystem = new FileSystemStub();\n            IUserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            IPreferences preferences = new UserFolderPreferences(fileSystem, userProfileDirectoryProvider, null);\n            HttpClient httpClient = new HttpClient();\n\n            return new HttpState(preferences, httpClient);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Suggestions/ServerPathCompletionTests.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.txt file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.HttpRepl.FileSystem;\nusing Microsoft.HttpRepl.OpenApi;\nusing Microsoft.HttpRepl.Preferences;\nusing Microsoft.HttpRepl.Suggestions;\nusing Microsoft.HttpRepl.UserProfile;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Suggestions\n{\n    public class ServerPathCompletionTests\n    {\n        [Fact]\n        public void GetCompletions_AbsoluteUri_ReturnsNull()\n        {\n            HttpState httpState = SetupHttpState();\n\n            IEnumerable<string> result = ServerPathCompletion.GetCompletions(httpState, \"https://github.com/\");\n\n            Assert.Null(result);\n        }\n\n        [Fact]\n        public void GetCompletions_WithBackslashes_ProperResults()\n        {\n            HttpState httpState = SetupHttpState();\n\n            IEnumerable<string> result = ServerPathCompletion.GetCompletions(httpState, \"child1\\\\g\");\n\n            Assert.Equal(2, result.Count());\n            Assert.Contains(\"child1/grandchild1\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"child1/grandchild2\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetCompletions_MixedCase_ProperResults()\n        {\n            HttpState httpState = SetupHttpState();\n\n            IEnumerable<string> result = ServerPathCompletion.GetCompletions(httpState, \"cHiLd1/gRaNd\");\n\n            Assert.Equal(2, result.Count());\n            Assert.Contains(\"child1/grandchild1\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"child1/grandchild2\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetCompletions_OnlyRoot_ProperResults()\n        {\n            HttpState httpState = SetupHttpState();\n\n            IEnumerable<string> result = ServerPathCompletion.GetCompletions(httpState, \"ch\");\n\n            Assert.Equal(2, result.Count());\n            Assert.Contains(\"child1\", result, StringComparer.OrdinalIgnoreCase);\n            Assert.Contains(\"child2\", result, StringComparer.OrdinalIgnoreCase);\n        }\n\n        [Fact]\n        public void GetCompletions_EmptyDirectory_ReturnsEmpty()\n        {\n            HttpState httpState = SetupHttpState();\n\n            IEnumerable<string> result = ServerPathCompletion.GetCompletions(httpState, \"child1/grandchild1/g\");\n\n            Assert.Empty(result);\n        }\n\n        [Fact]\n        public void GetCompletions_NoMatches_ReturnsEmpty()\n        {\n            HttpState httpState = SetupHttpState();\n\n            IEnumerable<string> result = ServerPathCompletion.GetCompletions(httpState, \"child1/abc\");\n\n            Assert.Empty(result);\n        }\n\n        [Fact]\n        public void GetCompletions_NullStructure_ReturnsNull()\n        {\n            HttpState httpState = SetupHttpState();\n            httpState.ApiDefinition = null;\n\n            IEnumerable<string> result = ServerPathCompletion.GetCompletions(httpState, \"c\");\n\n            Assert.Null(result);\n        }\n\n        private static HttpState SetupHttpState()\n        {\n            IFileSystem fileSystem = new FileSystemStub();\n            IUserProfileDirectoryProvider userProfileDirectoryProvider = new UserProfileDirectoryProvider();\n            IPreferences preferences = new UserFolderPreferences(fileSystem, userProfileDirectoryProvider, null);\n            HttpClient httpClient = new HttpClient();\n\n            HttpState httpState = new HttpState(preferences, httpClient);\n\n            DirectoryStructure structure = new DirectoryStructure(null);\n            DirectoryStructure child1 = structure.DeclareDirectory(\"child1\");\n            structure.DeclareDirectory(\"child2\");\n            child1.DeclareDirectory(\"grandchild1\");\n            child1.DeclareDirectory(\"grandchild2\");\n\n            ApiDefinition apiDefinition = new ApiDefinition();\n            apiDefinition.DirectoryStructure = structure;\n            httpState.ApiDefinition = apiDefinition;\n\n            return httpState;\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Telemetry/Events/PreferenceEventTests.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.Telemetry.Events;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Telemetry.Events\n{\n    public class PreferenceEventTests\n    {\n        [Theory]\n        [InlineData(\"get\", null)]\n        [InlineData(\"get\", \"\")]\n        [InlineData(\"get\", \" \")]\n        [InlineData(\"get\", \"editor.command.default\")]\n        [InlineData(\"get\", \"not.really.a.preference\")]\n        [InlineData(\"set\", null)]\n        [InlineData(\"set\", \"\")]\n        [InlineData(\"set\", \" \")]\n        [InlineData(\"set\", \"editor.command.default\")]\n        [InlineData(\"set\", \"not.really.a.preference\")]\n        public void Constructor_DoesNotThrow(string getOrSet, string preferenceName)\n        {\n            PreferenceEvent preferenceEvent = new PreferenceEvent(getOrSet, preferenceName);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.HttpRepl.Tests/Telemetry/Events/SetHeaderEventTests.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.txt file in the project root for more information.\n\nusing Microsoft.HttpRepl.Telemetry.Events;\nusing Xunit;\n\nnamespace Microsoft.HttpRepl.Tests.Telemetry.Events\n{\n    public class SetHeaderEventTests\n    {\n        [Theory]\n        [InlineData(null, false)]\n        [InlineData(\"\", false)]\n        [InlineData(\" \", false)]\n        [InlineData(\"Content-Type\", false)]\n        [InlineData(\"X-Custom-Header\", false)]\n        [InlineData(null, true)]\n        [InlineData(\"\", true)]\n        [InlineData(\" \", true)]\n        [InlineData(\"Content-Type\", true)]\n        [InlineData(\"X-Custom-Header\", true)]\n        public void Constructor_DoesNotThrow(string headerName, bool isValueEmpty)\n        {\n            SetHeaderEvent preferenceEvent = new SetHeaderEvent(headerName, isValueEmpty);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.Repl.Tests/ConsoleHandling/AnsiColorExtensionsTests.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.txt file in the project root for more information.\n\nusing Microsoft.Repl.ConsoleHandling;\nusing Xunit;\n\nnamespace Microsoft.Repl.Tests.ConsoleHandling\n{\n    public class AnsiColorExtensionsTests\n    {\n        [Theory]\n        [InlineData(\"BlackText\", AllowedColors.BoldBlack, \"\\x1B[30m\\x1B[1mBlackText\\x1B[39m\\x1B[39m\")]\n        [InlineData(\"RedText\", AllowedColors.BoldRed, \"\\x1B[31m\\x1B[1mRedText\\x1B[39m\\x1B[39m\")]\n        [InlineData(\"GreenText\", AllowedColors.BoldGreen, \"\\x1B[32m\\x1B[1mGreenText\\x1B[39m\\x1B[39m\")]\n        [InlineData(\"YellowText\", AllowedColors.BoldYellow, \"\\x1B[33m\\x1B[1mYellowText\\x1B[39m\\x1B[39m\")]\n        [InlineData(\"BlueText\", AllowedColors.BoldBlue, \"\\x1B[34m\\x1B[1mBlueText\\x1B[39m\\x1B[39m\")]\n        [InlineData(\"MagentaText\", AllowedColors.BoldMagenta, \"\\x1B[35m\\x1B[1mMagentaText\\x1B[39m\\x1B[39m\")]\n        [InlineData(\"CyanText\", AllowedColors.BoldCyan, \"\\x1B[36m\\x1B[1mCyanText\\x1B[39m\\x1B[39m\")]\n        [InlineData(\"WhiteText\", AllowedColors.BoldWhite, \"\\x1B[37m\\x1B[1mWhiteText\\x1B[39m\\x1B[39m\")]\n        public void SetColor_WithBold_ResponseIncludesColorAndBold(string text, AllowedColors color, string expected)\n        {\n            var result = text.SetColor(color);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Theory]\n        [InlineData(\"BlackText\", AllowedColors.Black, \"\\x1B[30mBlackText\\x1B[39m\")]\n        [InlineData(\"RedText\", AllowedColors.Red, \"\\x1B[31mRedText\\x1B[39m\")]\n        [InlineData(\"GreenText\", AllowedColors.Green, \"\\x1B[32mGreenText\\x1B[39m\")]\n        [InlineData(\"YellowText\", AllowedColors.Yellow, \"\\x1B[33mYellowText\\x1B[39m\")]\n        [InlineData(\"BlueText\", AllowedColors.Blue, \"\\x1B[34mBlueText\\x1B[39m\")]\n        [InlineData(\"MagentaText\", AllowedColors.Magenta, \"\\x1B[35mMagentaText\\x1B[39m\")]\n        [InlineData(\"CyanText\", AllowedColors.Cyan, \"\\x1B[36mCyanText\\x1B[39m\")]\n        [InlineData(\"WhiteText\", AllowedColors.White, \"\\x1B[37mWhiteText\\x1B[39m\")]\n        public void SetColor_WithoutBold_ResponseIncludesJustColor(string text, AllowedColors color, string expected)\n        {\n            var result = text.SetColor(color);\n\n            Assert.Equal(expected, result);\n        }\n\n        [Theory]\n        [InlineData(\"None\", AllowedColors.None, \"None\")]\n        [InlineData(\"InvalidColor\", (AllowedColors)0x50, \"InvalidColor\")]\n        public void SetColor_NoneOrInvalidColor_ReturnsText(string text, AllowedColors color, string expected)\n        {\n            var result = text.SetColor(color);\n\n            Assert.Equal(expected, result);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.Repl.Tests/DisposableTests.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.txt file in the project root for more information.\n\nusing System;\nusing Xunit;\n\nnamespace Microsoft.Repl.Tests\n{\n    public class DisposableTests\n    {\n        [Fact]\n        public void NonGeneric_Dispose_WithNullAction_DoesNotCrash()\n        {\n            using (Disposable disposable = new Disposable(null))\n            {\n\n            }\n        }\n\n        [Fact]\n        public void Generic_Dispose_WithNullProperty_DoesNotCrash()\n        {\n            using (Disposable<DisposableStub> disposable = new Disposable<DisposableStub>(null, null))\n            {\n\n            }\n        }\n\n        [Fact]\n        public void NonGeneric_Dispose_WithAction_CallsOnDispose()\n        {\n            bool onDisposeWasCalled = false;\n            Action onDispose = () => onDisposeWasCalled = true;\n\n            using (Disposable disposable = new Disposable(onDispose))\n            {\n\n            }\n\n            Assert.True(onDisposeWasCalled);\n        }\n\n        [Fact]\n        public void Generic_Dispose_WithAction_CallsOnDispose()\n        {\n            bool onDisposeWasCalled = false;\n            Action onDispose = () => onDisposeWasCalled = true;\n\n            using (Disposable<ClassStub> disposable = new Disposable<ClassStub>(new ClassStub(), onDispose))\n            {\n\n            }\n\n            Assert.True(onDisposeWasCalled);\n        }\n\n        [Fact]\n        public void Generic_Dispose_WithDisposable_CallsDispose()\n        {\n            DisposableStub disposableStub = new DisposableStub();\n            using (Disposable<DisposableStub> disposable = new Disposable<DisposableStub>(disposableStub, () => { }))\n            {\n\n            }\n\n            Assert.True(disposableStub.DisposeWasCalled);\n        }\n\n        public class ClassStub { }\n        public class DisposableStub : IDisposable\n        {\n            public bool DisposeWasCalled { get; private set; } = false;\n            public void Dispose()\n            {\n                DisposeWasCalled = true;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.Repl.Tests/InputManagerTests.cs",
    "content": "using Microsoft.HttpRepl.Fakes;\nusing Microsoft.Repl.Input;\nusing Xunit;\n\nnamespace Microsoft.Repl.Tests\n{\n    public class InputManagerTests\n    {\n        [Fact]\n        public void RemovePreviousCharacter_AtBeginning_DoesNothing()\n        {\n            // Arrange\n            string initialInput = \"echo on\";\n            int initialPosition = 0;\n            InputManager inputManager = new(initialInput, initialPosition);\n            MockedShellState mockedShellState = new(inputManager);\n\n            // Act\n            inputManager.RemovePreviousCharacter(mockedShellState);\n\n            // Assert\n            Assert.Equal(initialPosition, inputManager.CaretPosition);\n            Assert.Equal(initialInput, inputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public void RemovePreviousCharacter_AtEnd_RemovesLastCharacter()\n        {\n            // Arrange\n            string initialInput = \"echo on\";\n            int initialPosition = 7;\n            string expectedInput = \"echo o\";\n            int expectedPosition = 6;\n            InputManager inputManager = new(initialInput, initialPosition);\n            MockedShellState mockedShellState = new(inputManager);\n\n            // Act\n            inputManager.RemovePreviousCharacter(mockedShellState);\n\n            // Assert\n            Assert.Equal(expectedPosition, inputManager.CaretPosition);\n            Assert.Equal(expectedInput, inputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public void RemovePreviousCharacter_InMiddle_RemovesProperCharacter()\n        {\n            // Arrange\n            string initialInput = \"echo on\";\n            int initialPosition = 4;\n            string expectedInput = \"ech on\";\n            int expectedPosition = 3;\n            InputManager inputManager = new(initialInput, initialPosition);\n            MockedShellState mockedShellState = new(inputManager);\n\n            // Act\n            inputManager.RemovePreviousCharacter(mockedShellState);\n\n            // Assert\n            Assert.Equal(expectedPosition, inputManager.CaretPosition);\n            Assert.Equal(expectedInput, inputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public void RemoveCurrentCharacter_AtEnd_DoesNothing()\n        {\n            // Arrange\n            string initialInput = \"echo on\";\n            int initialPosition = 7;\n            InputManager inputManager = new(initialInput, initialPosition);\n            MockedShellState mockedShellState = new(inputManager);\n\n            // Act\n            inputManager.RemoveCurrentCharacter(mockedShellState);\n\n            // Assert\n            Assert.Equal(initialPosition, inputManager.CaretPosition);\n            Assert.Equal(initialInput, inputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public void RemoveCurrentCharacter_AtBeginning_RemovesFirstCharacter()\n        {\n            // Arrange\n            string initialInput = \"echo on\";\n            int initialPosition = 0;\n            string expectedInput = \"cho on\";\n            int expectedPosition = 0;\n            InputManager inputManager = new(initialInput, initialPosition);\n            MockedShellState mockedShellState = new(inputManager);\n\n            // Act\n            inputManager.RemoveCurrentCharacter(mockedShellState);\n\n            // Assert\n            Assert.Equal(expectedPosition, inputManager.CaretPosition);\n            Assert.Equal(expectedInput, inputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public void RemoveCurrentCharacter_InMiddle_RemovesProperCharacter()\n        {\n            // Arrange\n            string initialInput = \"echo on\";\n            int initialPosition = 4;\n            string expectedInput = \"echoon\";\n            int expectedPosition = 4;\n            InputManager inputManager = new(initialInput, initialPosition);\n            MockedShellState mockedShellState = new(inputManager);\n\n            // Act\n            inputManager.RemoveCurrentCharacter(mockedShellState);\n\n            // Assert\n            Assert.Equal(expectedPosition, inputManager.CaretPosition);\n            Assert.Equal(expectedInput, inputManager.GetCurrentBuffer());\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.Repl.Tests/Microsoft.Repl.Tests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>$(TestProjectTargetFramework)</TargetFramework>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Moq\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"Newtonsoft.Json\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"System.Net.Http\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"$(RepoSource)\\Microsoft.Repl\\Microsoft.Repl.csproj\" />\n    <ProjectReference Include=\"$(RepoTest)\\Microsoft.HttpRepl.Fakes\\Microsoft.HttpRepl.Fakes.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "test/Microsoft.Repl.Tests/ParserTests.cs",
    "content": "using Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.Repl.Tests\n{\n    public class ParserTests\n    {\n        [Fact]\n        public void ParserTests_Basic()\n        {\n            string testString = \"\\\"this is a test\\\" of \\\"Escape\\\\\\\\Sequences\\\\\\\"\\\"\";\n\n            CoreParser parser = new CoreParser();\n            ICoreParseResult result = parser.Parse(testString, 29);\n\n            Assert.Equal(3, result.Sections.Count);\n            Assert.Equal(2, result.SelectedSection);\n            Assert.Equal(0, result.SectionStartLookup[0]);\n            Assert.Equal(17, result.SectionStartLookup[1]);\n            Assert.Equal(20, result.SectionStartLookup[2]);\n            Assert.Equal(7, result.CaretPositionWithinSelectedSection);\n            Assert.Equal(29, result.CaretPositionWithinCommandText);\n            Assert.Equal(testString, result.CommandText);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.Repl.Tests/Parsing/CoreParseResultTests.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.txt file in the project root for more information.\n\nusing System.Linq;\nusing Microsoft.Repl.Parsing;\nusing Xunit;\n\nnamespace Microsoft.Repl.Tests.Parsing\n{\n    public class CoreParseResultTests\n    {\n        [Fact]\n        public void Slice_WithZero_ReturnsThis()\n        {\n            CoreParser parser = new CoreParser();\n            string commandText = \"set header content-type application/json\";\n            ICoreParseResult parseResult = parser.Parse(commandText, commandText.Length);\n\n            ICoreParseResult result = parseResult.Slice(0);\n\n            Assert.Same(parseResult, result);\n        }\n\n        [Fact]\n        public void Slice_WithTooMany_ReturnsDefaultResult()\n        {\n            CoreParser parser = new CoreParser();\n            string commandText = \"set header content-type application/json\";\n            ICoreParseResult parseResult = parser.Parse(commandText, commandText.Length);\n\n            ICoreParseResult result = parseResult.Slice(100);\n\n            Assert.Equal(0, result.CaretPositionWithinCommandText);\n            Assert.Equal(0, result.CaretPositionWithinSelectedSection);\n            Assert.Equal(string.Empty, result.CommandText);\n            Assert.Single(result.Sections);\n            Assert.Contains(string.Empty, result.Sections);\n            Assert.Equal(0, result.SelectedSection);\n            Assert.Single(result.SectionStartLookup);\n            Assert.Equal(0, result.SectionStartLookup.Single().Key);\n            Assert.Equal(0, result.SectionStartLookup.Single().Value);\n        }\n\n        [Theory]\n        [InlineData(\"set header content-type application/json\", 1, \"header content-type application/json\")]\n        [InlineData(\"set header content-type application/json\", 2, \"content-type application/json\")]\n        [InlineData(\"set header content-type application/json\", 3, \"application/json\")]\n        public void Slice_WithVariousSliceLengths_CorrectCommandTextOutput(string commandText, int toRemove, string expectedCommandText)\n        {\n            CoreParser parser = new CoreParser();\n            ICoreParseResult parseResult = parser.Parse(commandText, commandText.Length);\n\n            ICoreParseResult result = parseResult.Slice(toRemove);\n\n            Assert.Equal(expectedCommandText, result.CommandText);\n        }\n\n        [Fact]\n        public void Slice_WithCaretInSlicedRegion_CaretIsZero()\n        {\n            CoreParser parser = new CoreParser();\n            string commandText = \"set header content-type application/json\";\n            ICoreParseResult parseResult = parser.Parse(commandText, 5);\n\n            ICoreParseResult result = parseResult.Slice(2);\n\n            Assert.Equal(0, result.CaretPositionWithinCommandText);\n        }\n\n        [Theory]\n        [InlineData(\"set header content-type application/json\", 1, 26, 2)]\n        [InlineData(\"set header content-type application/json\", 2, 26, 1)]\n        [InlineData(\"set header content-type application/json\", 3, 26, 0)]\n        public void Slice_WithSelectedSection_SelectedSectionMoves(string commandText, int toRemove, int caretPosition, int expectedSelectedSection)\n        {\n            CoreParser parser = new CoreParser();\n            ICoreParseResult parseResult = parser.Parse(commandText, caretPosition);\n\n            ICoreParseResult result = parseResult.Slice(toRemove);\n\n            Assert.Equal(expectedSelectedSection, result.SelectedSection);\n        }\n\n        [Theory]\n        [InlineData(\"set base  https://localhost\", 3)]\n        [InlineData(\"run  c:\\\\script.txt\", 2)]\n        [InlineData(\"help  connect\", 2)]\n        [InlineData(\"set base \", 3)]\n        [InlineData(\"\", 1)]\n        [InlineData(\" set base https://localhost\", 3)]\n        public void Parse_WithDoubleSpace_RemovesEmptySections(string commandText, int expectedSectionCount)\n        {\n            CoreParser parser = new CoreParser();\n            ICoreParseResult parseResult = parser.Parse(commandText, commandText.Length + 1);\n\n            Assert.Equal(expectedSectionCount, parseResult.Sections.Count);\n        }\n\n        [Fact]\n        public void Parse_WithQuotesButNoSpaces_DoesNotCombineSections()\n        {\n            // Arrange\n            string commandText = \"GET --response:headers \\\"file.txt\\\" --response:body \\\"file.txt\\\"\";\n            int caretPosition = commandText.Length + 1;\n            CoreParser parser = new CoreParser();\n\n            int expectedSectionCount = 5;\n\n            // Act\n            ICoreParseResult parseResult = parser.Parse(commandText, caretPosition);\n\n            // Assert\n            Assert.Equal(expectedSectionCount, parseResult.Sections.Count);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Microsoft.Repl.Tests/ShellTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.HttpRepl.Fakes;\nusing Microsoft.Repl.Commanding;\nusing Moq;\nusing Xunit;\n\nnamespace Microsoft.Repl.Tests\n{\n    public class ShellTests\n    {\n        [Fact]\n        public async Task RunAsync_WithUpArrowKeyPress_UpdatesCurrentBufferWithPreviousCommand()\n        {\n            string previousCommand = \"set base \\\"https://localhost:44366/\\\"\";\n            ConsoleKeyInfo consoleKeyInfo = new ConsoleKeyInfo(keyChar: '\\0',\n                key: ConsoleKey.UpArrow,\n                shift: false,\n                alt: false,\n                control: false);\n            Shell shell = CreateShell(consoleKeyInfo,\n                previousCommand: previousCommand,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer has previous command after the UpArrow key press event\n            Assert.Equal(previousCommand, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(previousCommand.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithUpArrowKeyPressWithLongPreviousCommand_UpdatesCurrentBufferWithPreviousCommand()\n        {\n            string previousCommand = \"connect \\\"https://localhost:44366/\\\" --base \\\"https://localhost:44366/api/v2/\\\" --openapi \\\"https://localhost:44366/openapi/v2/openapi.yaml\\\"\";\n            ConsoleKeyInfo consoleKeyInfo = new ConsoleKeyInfo(keyChar: '\\0',\n                key: ConsoleKey.UpArrow,\n                shift: false,\n                alt: false,\n                control: false);\n            Shell shell = CreateShell(consoleKeyInfo,\n                previousCommand: previousCommand,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer has previous command after the UpArrow key press event\n            Assert.Equal(previousCommand, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(previousCommand.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithUpArrowKeyPress_VerifyInputBufferContentsBeforeAndAfterKeyPressEvent()\n        {\n            string previousCommand = \"set base \\\"https://localhost:44366/\\\"\";\n            ConsoleKeyInfo consoleKeyInfo = new ConsoleKeyInfo(keyChar: '\\0',\n                key: ConsoleKey.UpArrow,\n                shift: false,\n                alt: false,\n                control: false);\n            Shell shell = CreateShell(consoleKeyInfo,\n                previousCommand: previousCommand,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            // Verify the input buffer is empty before the UpArrow key press event\n            Assert.Equal(string.Empty, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(0, shell.ShellState.InputManager.CaretPosition);\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer has previous command after the UpArrow key press event\n            Assert.Equal(previousCommand, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(previousCommand.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithDownArrowKeyPress_UpdatesCurrentBufferWithNextCommand()\n        {\n            string nextCommand = \"get\";\n            ConsoleKeyInfo consoleKeyInfo = new ConsoleKeyInfo(keyChar: '\\0',\n                key: ConsoleKey.DownArrow,\n                shift: false,\n                alt: false,\n                control: false);\n            Shell shell = CreateShell(consoleKeyInfo,\n                previousCommand: null,\n                nextCommand: nextCommand,\n                out CancellationTokenSource cancellationTokenSource);\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer has next command after the DownArrow key press event\n            Assert.Equal(nextCommand, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(nextCommand.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithDeleteKeyPress_DeletesCurrentCharacterInTheInputBuffer()\n        {\n            ConsoleKeyInfo[] keys = new[]\n            {\n                GetConsoleKeyInfo('g'),\n                GetConsoleKeyInfo('e'),\n                GetConsoleKeyInfo('t'),\n                GetConsoleKeyInfo(ConsoleKey.LeftArrow),\n                GetConsoleKeyInfo(ConsoleKey.Delete)\n            };\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            string inputBufferTextAfterKeyPress = \"ge\";\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer contents after Delete key press event\n            Assert.Equal(inputBufferTextAfterKeyPress, shell.ShellState.InputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public async Task RunAsync_WithBackspaceKeyPress_DeletesPreviousCharacterInTheInputBuffer()\n        {\n            ConsoleKeyInfo[] keys = new[]\n            {\n                GetConsoleKeyInfo('g'),\n                GetConsoleKeyInfo('e'),\n                GetConsoleKeyInfo('t'),\n                GetConsoleKeyInfo(ConsoleKey.LeftArrow),\n                GetConsoleKeyInfo(ConsoleKey.Backspace)\n            };\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            string inputBufferTextAfterKeyPress = \"gt\";\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer contents after Backspace key press event\n            Assert.Equal(inputBufferTextAfterKeyPress, shell.ShellState.InputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public async Task RunAsync_WithEscapeKeyPress_UpdatesInputBufferWithEmptyString()\n        {\n            ConsoleKeyInfo[] keys = new[]\n{\n                GetConsoleKeyInfo('g'),\n                GetConsoleKeyInfo('e'),\n                GetConsoleKeyInfo('t'),\n                GetConsoleKeyInfo(ConsoleKey.Escape),\n            };\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            string inputBufferTextAfterKeyPress = string.Empty;\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer contents after Escape key press event\n            Assert.Equal(inputBufferTextAfterKeyPress, shell.ShellState.InputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public async Task RunAsync_WithCtrlUKeyPress_UpdatesInputBufferWithEmptyString()\n        {\n            ConsoleKeyInfo[] keys = new[]\n            {\n                GetConsoleKeyInfo('g'),\n                GetConsoleKeyInfo('e'),\n                GetConsoleKeyInfo('t'),\n                new(keyChar: '\\0', key: ConsoleKey.U, shift: false, alt: false, control: true),\n            };\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            string inputBufferTextAfterKeyPress = string.Empty;\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer contents after Ctrl + U key press event\n            Assert.Equal(inputBufferTextAfterKeyPress, shell.ShellState.InputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public async Task RunAsync_WithInsertKeyPress_FlipsIsOverwriteModeInInputManager()\n        {\n            ConsoleKeyInfo consoleKeyInfo = new ConsoleKeyInfo(keyChar: '\\0',\n                key: ConsoleKey.Insert,\n                shift: false,\n                alt: false,\n                control: false);\n            Shell shell = CreateShell(consoleKeyInfo,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify IsOverwriteMode flag in input manager is set to false after Insert key press event\n            Assert.True(shell.ShellState.InputManager.IsOverwriteMode);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithUnhandledKeyPress_DoesNothing()\n        {\n            ConsoleKeyInfo[] keys = new[]\n            {\n                GetConsoleKeyInfo('g'),\n                GetConsoleKeyInfo('e'),\n                GetConsoleKeyInfo('t'),\n                GetConsoleKeyInfo(ConsoleKey.F1),\n            };\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            string inputBufferText = \"get\";\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer contents after F1 key press event\n            Assert.Equal(inputBufferText, shell.ShellState.InputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public async Task RunAsync_WithTabKeyPress_UpdatesInputBufferWithFirstEntryFromSuggestionList()\n        {\n            ConsoleKeyInfo[] keys = new[]\n            {\n                GetConsoleKeyInfo('c'),\n                GetConsoleKeyInfo(ConsoleKey.Tab),\n            };\n\n            Shell shell = CreateShell(keys,\n                 previousCommand: null,\n                 nextCommand: null,\n                 out CancellationTokenSource cancellationTokenSource);\n\n            string inputBufferTextAfterKeyPress = \"cd\";\n\n            DefaultCommandDispatcher<object> defaultCommandDispatcher = shell.ShellState.CommandDispatcher as DefaultCommandDispatcher<object>;\n            string cdCommandName = \"cd\";\n            defaultCommandDispatcher.AddCommand(new MockCommand(cdCommandName));\n            string clearCommandName = \"clear\";\n            defaultCommandDispatcher.AddCommand(new MockCommand(clearCommandName));\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer contents after tab key press event\n            Assert.Equal(inputBufferTextAfterKeyPress, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(inputBufferTextAfterKeyPress.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithShiftTabKeyPress_UpdatesInputBufferWithLastEntryFromSuggestionList()\n        {\n            ConsoleKeyInfo[] keys = new[]\n            {\n                GetConsoleKeyInfo('c'),\n                new(keyChar: '\\0', key: ConsoleKey.Tab, shift: true, alt: false, control: false),\n            };\n\n            Shell shell = CreateShell(keys,\n                 previousCommand: null,\n                 nextCommand: null,\n                 out CancellationTokenSource cancellationTokenSource);\n\n            string inputBufferTextAfterKeyPress = \"clear\";\n\n            DefaultCommandDispatcher<object> defaultCommandDispatcher = shell.ShellState.CommandDispatcher as DefaultCommandDispatcher<object>;\n            string cdCommandName = \"cd\";\n            defaultCommandDispatcher.AddCommand(new MockCommand(cdCommandName));\n            string clearCommandName = \"clear\";\n            defaultCommandDispatcher.AddCommand(new MockCommand(clearCommandName));\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer contents after Shift + Tab key press event\n            Assert.Equal(inputBufferTextAfterKeyPress, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(inputBufferTextAfterKeyPress.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithTabKeyPressAndNoSuggestions_DoesNothing()\n        {\n            ConsoleKeyInfo[] keys = new[]\n            {\n                GetConsoleKeyInfo('z'),\n                GetConsoleKeyInfo(ConsoleKey.Tab),\n            };\n\n            Shell shell = CreateShell(keys,\n                 previousCommand: null,\n                 nextCommand: null,\n                 out CancellationTokenSource cancellationTokenSource);\n\n            string inputBufferTextAfterKeyPress = \"z\";\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer contents after tab key press event\n            Assert.Equal(inputBufferTextAfterKeyPress, shell.ShellState.InputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public async Task RunAsync_WithShiftTabKeyPressAndNoSuggestions_DoesNothing()\n        {\n            ConsoleKeyInfo[] keys = new[]\n            {\n                GetConsoleKeyInfo('z'),\n                new(keyChar: '\\0', key: ConsoleKey.Tab, shift: true, alt: false, control: false)\n            };\n\n            Shell shell = CreateShell(keys,\n                 previousCommand: null,\n                 nextCommand: null,\n                 out CancellationTokenSource cancellationTokenSource);\n\n            string inputBufferTextAfterKeyPress = \"z\";\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Verify the input buffer contents after Shift + Tab key press event\n            Assert.Equal(inputBufferTextAfterKeyPress, shell.ShellState.InputManager.GetCurrentBuffer());\n        }\n\n        [Fact]\n        public async Task RunAsync_WithEnterKeyPress_UpdatesInputBufferWithEmptyString()\n        {\n            string input = \"set base \\\"https://localhost:44366/\\\"\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.Enter, shift: false, alt: false, control: false));\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(string.Empty, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(0, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithLeftArrowKeyPress_VerifyCaretPositionWasUpdated()\n        {\n            string input = \"set base \\\"https://localhost:44366/\\\"\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            IShellState shellState = shell.ShellState;\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(input.Length - 1, shellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithControlLeftArrowKeyPress_VerifyCaretPositionWasUpdated()\n        {\n            string input = \"set base \\\"https://localhost:44366/\\\"\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: true));\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            IShellState shellState = shell.ShellState;\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(9, shellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithRightArrowKeyPress_VerifyCaretPositionWasUpdated()\n        {\n            string input = \"set base \\\"https://localhost:44366/\\\"\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.RightArrow, shift: false, alt: false, control: false));\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            IShellState shellState = shell.ShellState;\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(input.Length - 2, shellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithControlRightArrowKeyPress_VerifyCaretPositionWasUpdated()\n        {\n            string input = \"set base \\\"https://localhost:44366/\\\"\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.RightArrow, shift: false, alt: false, control: true));\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            IShellState shellState = shell.ShellState;\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(input.Length, shellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithHomeKeyPress_VerifyCaretPositionWasUpdated()\n        {\n            string input = \"set base \\\"https://localhost:44366/\\\"\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.Home, shift: false, alt: false, control: false));\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            IShellState shellState = shell.ShellState;\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(0, shellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithCtrlAKeyPress_VerifyCaretPositionWasUpdated()\n        {\n            string input = \"set base \\\"https://localhost:44366/\\\"\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.A, shift: false, alt: false, control: true));\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            IShellState shellState = shell.ShellState;\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(0, shellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithEndKeyPress_VerifyCaretPositionWasUpdated()\n        {\n            string input = \"set base \\\"https://localhost:44366/\\\"\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.End, shift: false, alt: false, control: false));\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            IShellState shellState = shell.ShellState;\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(input.Length, shellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithCtrlEKeyPress_VerifyCaretPositionWasUpdated()\n        {\n            string input = \"set base \\\"https://localhost:44366/\\\"\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.LeftArrow, shift: false, alt: false, control: false));\n            keys.Add(new(keyChar: '\\0', key: ConsoleKey.E, shift: false, alt: false, control: true));\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(input.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithInvalidCommand_VerifyInputBufferIsCleared()\n        {\n            string input = \"this is an invalid command\\n\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n\n            Shell shell = CreateShell(keys,\n                previousCommand: null,\n                nextCommand: null,\n                out CancellationTokenSource cancellationTokenSource);\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Empty(shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(0, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithTwoInvalidCommandsAndTwoUpArrows_VerifyInputBufferIsCorrect()\n        {\n            string commandOne = \"longer invalid command text\";\n            string commandTwo = \"small invalid cmd\";\n            string input = $\"{commandOne}\\n{commandTwo}\\n\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(input);\n            keys.Add(GetConsoleKeyInfo(ConsoleKey.UpArrow));\n            keys.Add(GetConsoleKeyInfo(ConsoleKey.UpArrow));\n\n            Shell shell = CreateShell(keys, out CancellationTokenSource cancellationTokenSource);\n\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            Assert.Equal(commandOne,shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(commandOne.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithNullCharacters_NullCharactersIgnored()\n        {\n            // Arrange\n            string command = \"Command With \\0 Character\";\n            string expectedCommand = command.Replace(\"\\0\", \"\");\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(command);\n\n            Shell shell = CreateShell(keys, out CancellationTokenSource cancellationTokenSource);\n\n            // Act\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Assert\n            Assert.Equal(expectedCommand, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(expectedCommand.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        [Fact]\n        public async Task RunAsync_WithNullCharactersAndBackspaces_NullCharactersIgnored()\n        {\n            // Arrange\n            string command = \"Command With \\0 \";\n            string expectedCommand = \"Command Wit\";\n            List<ConsoleKeyInfo> keys = GetConsoleKeyInfo(command);\n            keys.Add(GetConsoleKeyInfo(ConsoleKey.Backspace));\n            keys.Add(GetConsoleKeyInfo(ConsoleKey.Backspace));\n            keys.Add(GetConsoleKeyInfo(ConsoleKey.Backspace));\n\n            Shell shell = CreateShell(keys, out CancellationTokenSource cancellationTokenSource);\n\n            // Act\n            await shell.RunAsync(cancellationTokenSource.Token);\n\n            // Assert\n            Assert.Equal(expectedCommand, shell.ShellState.InputManager.GetCurrentBuffer());\n            Assert.Equal(expectedCommand.Length, shell.ShellState.InputManager.CaretPosition);\n        }\n\n        private static Shell CreateShell(IEnumerable<ConsoleKeyInfo> consoleKeyInfo,\n            string previousCommand,\n            string nextCommand,\n            out CancellationTokenSource cancellationTokenSource)\n        {\n            DefaultCommandDispatcher<object> defaultCommandDispatcher = DefaultCommandDispatcher.Create(x => { }, new object());\n\n            cancellationTokenSource = new CancellationTokenSource();\n            MockConsoleManager mockConsoleManager = new MockConsoleManager(consoleKeyInfo, cancellationTokenSource);\n\n            Mock<ICommandHistory> mockCommandHistory = new Mock<ICommandHistory>();\n            mockCommandHistory.Setup(s => s.GetPreviousCommand())\n                .Returns(previousCommand);\n            mockCommandHistory.Setup(s => s.GetNextCommand())\n                .Returns(nextCommand);\n\n            ShellState shellState = new ShellState(defaultCommandDispatcher,\n                consoleManager: mockConsoleManager,\n                commandHistory: mockCommandHistory.Object);\n\n            return new Shell(shellState);\n        }\n\n        private static Shell CreateShell(IEnumerable<ConsoleKeyInfo> consoleKeyInfo, out CancellationTokenSource cancellationTokenSource)\n        {\n            DefaultCommandDispatcher<object> defaultCommandDispatcher = DefaultCommandDispatcher.Create(x => { }, new object());\n\n            cancellationTokenSource = new CancellationTokenSource();\n            MockConsoleManager mockConsoleManager = new MockConsoleManager(consoleKeyInfo, cancellationTokenSource);\n\n            ShellState shellState = new ShellState(defaultCommandDispatcher,\n                consoleManager: mockConsoleManager);\n\n            return new Shell(shellState);\n        }\n\n        private static Shell CreateShell(ConsoleKeyInfo consoleKeyInfo, string previousCommand, string nextCommand, out CancellationTokenSource cancellationTokenSource)\n        {\n            return CreateShell(new ConsoleKeyInfo[] { consoleKeyInfo }, previousCommand, nextCommand, out cancellationTokenSource);\n        }\n\n        /// <summary>\n        /// Converts a string into the series of ConsoleKeyInfo instances that would be used\n        /// to type the string in the console.\n        /// </summary>\n        private static List<ConsoleKeyInfo> GetConsoleKeyInfo(string text)\n        {\n            List<ConsoleKeyInfo> keys = new();\n\n            text = text.Replace(\"\\r\\n\", \"\\n\");\n\n            foreach (char c in text)\n            {\n                ConsoleKeyInfo consoleKeyInfo = GetConsoleKeyInfo(c);\n                keys.Add(consoleKeyInfo);\n            }\n\n            return keys;\n        }\n\n        /// <summary>\n        /// Builds a ConsoleKeyInfo object with the specified console key, the null keyChar ('\\0') and no modifiers.\n        /// Intended for non-printable keystrokes.\n        /// </summary>\n        private static ConsoleKeyInfo GetConsoleKeyInfo(ConsoleKey key) => new('\\0', key, shift: false, alt: false, control: false);\n\n        /// <summary>\n        /// Builds a ConsoleKeyInfo that could produce the specified character\n        /// </summary>\n        private static ConsoleKeyInfo GetConsoleKeyInfo(char keyChar)\n        {\n            return keyChar switch\n            {\n                >= 'a' and <= 'z'        => new(keyChar: keyChar, key: (ConsoleKey)(keyChar - 32), shift: false, alt: false, control: false),\n                >= 'A' and <= 'Z'        => new(keyChar: keyChar, key: (ConsoleKey)keyChar,        shift: true,  alt: false, control: false),\n                >= '0' and <= '9' or ' ' => new(keyChar: keyChar, key: (ConsoleKey)keyChar,        shift: false, alt: false, control: false),\n                ':'                      => new(keyChar: keyChar, key: ConsoleKey.Oem1,            shift: true,  alt: false, control: false),\n                '/'                      => new(keyChar: keyChar, key: ConsoleKey.Oem2,            shift: false, alt: false, control: false),\n                '\"'                      => new(keyChar: keyChar, key: ConsoleKey.Oem7,            shift: true,  alt: false, control: false),\n                '\\n'                     => new(keyChar: '\\r',    key: ConsoleKey.Enter,           shift: false, alt: false, control: false),\n                '\\0'                     => new(keyChar: keyChar, key: ConsoleKey.Oem102,          shift: false, alt: false, control: false),\n                _                        => throw new InvalidOperationException($\"Test setup does not support '{keyChar}' yet.\"),\n            };\n        }\n    }\n}\n"
  }
]