[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# Ignore exe's\n*.exe\n*.exe.config\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n*.generated.cs\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbuild/\nbld/\n[Bb]in/\n[Oo]bj/\n\n# Visual Studo 2015 cache/options directory\n.vs/\n\n# Rider ide directory\n.idea/\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# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding addin-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings \n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n\n# Windows Azure Build Output\ncsx/\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\n*.[Cc]ache\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\nbower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n/test/Etg.Yams.Test/Data/Exes/*.exe\n"
  },
  {
    "path": "Docs/Continuous_Integration.md",
    "content": "# Continuous Integration with YAMS and VSTS\n\nIn this tutorial, we will demonstrate how to use YAMS in a continuous integration environments. We will use VSTS as an example, but the concepts discussed can be easily adapted to another platform. We will also pair YAMS with cloud services to get the best of both words.\n\nWe will automate the deployment of two YAMS clusters:\n* A Web Api cluster.\n* An Orleans cluster.\n\nWe could deploy both applications to the same cluster, but we chose to use two clusters because that will allow us to scale the two clusters independently.\n\nFinally, we will show how you can add support for multiples configuration environments (e.g. dev, prod) to your YAMS applications.\n\n## Deploy YAMS\n\nTo deploy services with YAMS, the YAMS host itself need to be deployed to the virtual machines where the services will be deployed. We use Azure Cloud Services for this.\n\nThe [Deploy YAMS tutorial](Deploy_YAMS.md) tutorial shows how YAMS can be deployed to a cloud service.\n\n### Multiple configuration environments\n\nIn order to support multiple configuration environments (e.g. dev, prod), we will add the environment name to the YAMS cluster properties. In the worker role shown in [Deploy YAMS tutorial](Deploy_YAMS.md), add the `EnvironmentName` cluster property as show below:\n\n```csharp\n            string clusterId = \"WebApi\";\n            YamsConfig yamsConfig = new YamsConfigBuilder(\n                // mandatory configs\n                clusterId: clusterId,\n                instanceUpdateDomain: RoleEnvironment.CurrentRoleInstance.UpdateDomain.ToString(),\n                instanceId: RoleEnvironment.CurrentRoleInstance.Id,\n                applicationInstallDirectory: RoleEnvironment.GetLocalResource(\"LocalStoreDirectory\").RootPath)\n                // optional configs\n                .SetCheckForUpdatesPeriodInSeconds(5)\n                .SetApplicationRestartCount(3)\n                .AddClusterProperty(\"EnvironmentName\", RoleEnvironment.GetConfigurationSettingValue(\"EnvironmentName\"))\n                .AddClusterProperty(\"DeploymentId\", GetDeploymentId())\n                .Build();\n```\n\nFor the above to work, you need to add the `EnvironmentName` to your cloud service `ServiceDefinition.csdef` and the corresponding `ServiceConfiguration.*.cscfg` files.\n\nNotice that we have also added the `DeploymentId` as a cluster property and that we have named the cluster `WebApi` (we will take advantage of the `DeploymentId` property later in this tutorial).\n\n\n### Multiple clusters\n\nTo host a second YAMS cluster in the same cloud service, simply add a second worker role to your solution. The second worker role will be used to host the cluster where Orleans is deployed, and the cluster id will be `Orleans`.\n\n### Deploy with Visual Studio\n\nIf you followed the steps in [Deploy YAMS tutorial](Deploy_YAMS.md) and the steps above, you should be ready to deploy YAMS to a cloud service with two worker role, one hosting the Web Api and another hosting Orleans.\n\nYou have also configured the YAMS clusters so that the deployment id and the environment name are passed down to YAMS as cluster properties and available to be used as command line arguments to start YAMS applications. In fact, cluster properties can be used in the `AppConfig.json` file of a YAMS application and will be resolved to the actual value if referenced as follows: `${Cluster_Property_Name}` (e.g. ${EnvironmentName}). See [YAMS Overview](Overview.md) for more information about the `AppConfig.json` file.\n\nFinally, deploy your YAMS clusters to the cloud service using visual studio. You will typically need to deploy the cloud service only once and then manage applications with YAMS.\n\n## Deploy YAMS applications with VSTS\n\nNow that the YAMS cluster is up and running, it's time to setup VSTS so that YAMS applications are automatically deployed.\n\nMake sure that your WebApi and Orleans applications have corresponding `AppConfig.json` files and are configured so that the `EnvironmentName` and `DeploymentId` are passed as command line arguments as follows:\n\n```json\n{\n  \"ExeName\": \"HelloService.WebApi.exe\",\n  \"ExeArgs\": \"${EnvironmentName} ${DeploymentId}\"\n}\n```\n\n```json\n{\n  \"ExeName\": \"HelloService.Orleans.exe\",\n  \"ExeArgs\": \"${EnvironmentName} ${DeploymentId}\"\n}\n```\n\nThe applications can then load different configuration based on the `EnvironmentName` (this is quite easy to setup using `Microsoft.Extensions.Configuration` for example).\n\nThe `DeploymentId` is only passed down so it can be used as a silo name (don't worry about this if you are not using Orleans).\n\n### Setup your build\n\nSetup your VSTS build so that the build artifacts are as follows:\n\n```\nBuild\\drop\\HelloService.WebApi\\\nBuild\\drop\\HelloService.Orleans\\\n```\n\nThe directories above should contain all the binaries and configuration needed to start your applications.\n\n### Setup VSTS\n\nTo deploy YAMS, we will use the YAMS powershell cmdlets.\n\n* Add a `Download Package` task to your VSTS release definition and select the latest version of `Etg.Yams.Powershell`.\n* Use `$(System.DefaultWorkingDirectory)/YamsPowershell` as a destination directory.\n* Add an `Azure Powershell` task to your VSTS release definition and add the following to it:\n\nScripts Arguments: \n```\n-WorkingDir \"$(System.DefaultWorkingDirectory)\" -ConnectionString \"$(StorageConnectionString)\" -Version \"1.0.$(Release.ReleaseId)\"\n```\n\nInline Scripts:\n```powershell\nParam(\n  [string]$ConnectionString,\n  [string]$Version,\n  [string]$WorkingDir\n)\n\n$BinDir = \"$WorkingDir\\Build\\drop\"\n\nImport-Module $WorkingDir\\YamsPowershell\\content\\Etg.Yams.Powershell.dll\nInstall-Applications -ConnectionString $ConnectionString -AppsIds \"HelloService.WebApi\",\"HelloService.Orleans\" -ClustersIds \"WebApi\",\"Orleans\" -BinariesPath \"$BinDir\\HelloService.WebApi\",\"$BinDir\\HelloService.Orleans\\\" -Versions $Version,$Version -WaitForDeploymentsToComplete $true\n```\n\nNote that this assumes that you already have a storage account configured for YAMS and that you have added `StorageConnectionString` variable to VSTS (or feel free to use any different way to propagate your connection string to the powershell script).\n\nThat's it! \n\nAll you need to do now is to configure your deployment triggers in VSTS (e.g. deploy on every check-in to master) and you should have 1-2 minute VSTS deployments!\n\n\n## Add Support for VIP Swaps\n\nIn some cases, one may not feel confident using a rolling upgrade in a production environment because there is a chance that the deployed service will experience difficulties starting up. A popular approach to avoid such issues is to deploy first to a staging environment, test and warm up the deployment, and then perform a VIP swap.\n\nYAMS does not have native support for VIP swaps but one can easily achieve VIP swaps with YAMS when combined with Azure cloud services. The trick is to use the cloud service deployment id as a prefix in the Yams cluster id. Follow the following steps to achieve this.\n\n* Use the deployment id of your cloud service as a prefix to your YAMS cluster id when you start your worker role:\n```csharp\nstring clusterId = $\"{RoleEnvironment.GetConfigurationSettingValue(\"ClusterId\")}_{RoleEnvironment.DeploymentId}\";\n```\n* Use the same deployment id above in your VSTS task\n\n```powershell\nParam(\n  [string]$ConnectionString,\n  [string]$Version,\n  [string]$WorkingDir\n)\n\n$BinDir = \"$WorkingDir\\Build\\drop\"\n\nImport-Module $WorkingDir\\YamsPowershell\\content\\Etg.Yams.Powershell.dll\n\n$DeploymentId = (Get-AzureDeployment -ServiceName $(ServiceName) -Slot Staging).DeploymentId\n\nInstall-Applications -ConnectionString $ConnectionString -AppsIds \"NotificationService\",\"NotificationService.Silo\" -ClustersIds \"FrontEnd_$(DeploymentId)\",\"Orleans_$(DeploymentId)\" -BinariesPath \"$BinDir\\NotificationService\",\"$BinDir\\NotificationService.Silo\\\" -Versions $Version,$Version -WaitForDeploymentsToComplete $true\n```\n\nWith this setup, the YAMS applications will be deployed to the *Staging* slot instead of the *Production* slot. Once the service is deployed, warmed up and tested, simply VIP swap using the cloud service portal or a powershell VSTS task.\n"
  },
  {
    "path": "Docs/Contributor_Guide.md",
    "content": "# YAMS Contributor Guide\n\n## How to debug YAMS?\n\nTo debug YAMS code, simply use the `Etg.Yams.Host` console app available in the Etg.Yams solution (Make `Etg.Yams.Host` a startup project and hit `F5`). You can then easily make changes to YAMS code and run the console app.\n\nThe `Etg.Yams.Host` console app will start a YAMS cluster with the following properties:\n* ClusterId = \"TestClusterId\"\n* InstanceId = \"instance_0\"\n* Update domain = \"0\"\n* The current directory (e.g. `Etg.Yams.Host\\bin\\Debug`) is where binaries will be installed.\n* The storage account used by default is the development storage (change it as needed but make sure to not check in your connection string!).\n\nDon't forget to submit a pull request when you're done fixing an issue or adding a new feature!\n "
  },
  {
    "path": "Docs/Deploy&Host_an_App_in_YAMS.md",
    "content": "# Overview\n\nIn this tutorial, we will create a simple application and deploy it to YAMS. We will learn the following:\n* How to deploy an app for the first time.\n* How to deploy multiple apps.\n* How to update an app (to perform bug fixes or upgrades).\n* How to deploy two versions of the same app side-by-side.\n* How to remove or revert a deployment.\n\n# Create an App\nLet's create a simple web Api that we will later deploy to YAMS (**note** that any **exe** can be deployed to YAMS but we chose a Web Api in this example because we can interact with it). To deploy an app to YAMS, the app must contain an **exe** that can be used to start the app. Follow the steps below to create a web Api that can be started with an **exe**.\n\n* Create a new *Console Application* project in visual studio and name it *WebApp*.\n* Install the NuGet package `Microsoft.AspNet.WebApi.OwinSelfHost` to the *WebApp* project.\n* Rename the `Program.cs` file to `App.cs` and add the following content to it:\n\n```csharp\nusing System;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Sockets;\n\nnamespace WebApp\n{\n    public class App\n    {\n        public static string Id;\n        public static string Version;\n        public static string ClusterId;\n\n        static void Main(string[] args)\n        {\n            Id = args[0];\n            Version = args[1];\n            ClusterId = args[2];\n\n            string baseUrl = string.Format(\"http://{0}/{1}/\", GetIpAddress(), Id);\n            Console.WriteLine(\"Url is: \" + baseUrl);\n\n            // Start OWIN host \n            Microsoft.Owin.Hosting.WebApp.Start<Startup>(url: baseUrl);\n            Console.WriteLine(\"WebApp has been started successfully\");\n            Console.ReadLine(); \n\n        }\n\n        private static string GetIpAddress()\n        {\n            var host = Dns.GetHostEntry(Dns.GetHostName());\n            return host.AddressList.First(x => x.AddressFamily == AddressFamily.InterNetwork).ToString();\n        }\n    }\n}\n```\n\n* Create a class called `Startup` and add the following to it:\n\n```csharp\nusing System;\nusing System.Web.Http;\nusing Owin;\n\nnamespace WebApp\n{\n    class Startup\n    {\n        // This code configures Web API. The Startup class is specified as a type\n        // parameter in the WebApp.Start method.\n        public void Configuration(IAppBuilder appBuilder)\n        {\n            // Configure Web API for self-host. \n            HttpConfiguration config = new HttpConfiguration();\n            config.MapHttpAttributeRoutes();\n            config.Routes.MapHttpRoute(\n                name: \"DefaultApi\",\n                routeTemplate: \"api/{controller}/{id}\",\n                defaults: new { id = RouteParameter.Optional }\n            );\n            config.EnsureInitialized();\n            appBuilder.UseWebApi(config);\n        } \n    }\n}\n```\n\n* Create an `ApplicationController` class and add the following to it:\n\n```csharp\nusing System.Web.Http;\nusing Newtonsoft.Json.Linq;\n\nnamespace WebApp\n{\n    [RoutePrefix(\"application\")]\n    public class ApplicationController : ApiController\n    {\n        [Route(\"info\")]\n        public JObject GetInfo()\n        {\n            string json = string.Format(@\"\n                {{\n                    'Id': '{0}',\n                    'Version': '{1}',\n                    'Yams Cluster Id': '{2}'\n                }}\n                \", App.Id, App.Version, App.ClusterId);\n\n            return JObject.Parse(json);\n        }\n    }\n}\n```\n\nSo far, we have created a simple web Api application. The app exposes an Api that allows one to obtain basic information such as the *id* and the *version* of the app.\n\nBefore deploying an application in YAMS, we need to add a YAMS specific configuration file to the root of the application.\n* Add an `AppConfig.json` file to the root of the WebApp project.\n* In the `AppConfig.json` file properties, under \"Copy to Output Directory\", select either \"Copy Always\" or \"Copy if Newer\".\n* Add the following to the `AppConfig.json` file:\n\n```json\n{\n    \"ExeName\": \"WebApp.exe\",\n    \"ExeArgs\": \"${Id} ${Version} ${ClusterId}\"\n}\n```\n\nNotice the use of `${symbol}` in the config file. The values of these symbols will be resolved by YAMS at runtime. The set of all supported symbols is available [here](Deploy_YAMS.md). In this case, we are passing the *id*, *version* and *cloud service deployment id* to the *WebApp.exe* which is expecting these arguments (see the `Main` function of the app).\n\nFinally, build the app and make sure that the exe has been created and that the `AppConfig.json` file has been copied to the output.\n\n# Deploy the App\nYAMS relies on blob storage to download and deploy the binaries of an application. In fact, a YAMS cluster is associated with a storage account where all applications binaries are uploaded. See the [Deploy YAMS](Deploy_YAMS.md) tutorial to learn more on how to deploy a YAMS cluster.\n\nTo deploy **WebApp** to YAMS, follow the steps below:\n* In the `applications` container (at the root of the YAMS blob storage), create `WebApp/1.0.0` directory.\n* Upload the output of the *WebApp* project to the `applications/WebApp/1.0.0` blob directory.\n* Tell YAMS to download and deploy the app to the cloud service by adding a corresponding entry in the `DeploymentConfig.json` file located at the root of the `applications` folder:\n\n```json\n{\n\t\"Applications\":\n\t[\n\t\t{\n\t\t\t\"Id\": \"WebApp\",\n\t\t\t\"Version\": \"1.0.0\",\n\t\t\t\"TargetClusters\": [ \"MY_CLUSTER_ID\" ]\n\t\t}\n\t]\n}\n```\n\nThe application should be up and running in a matter of seconds. To test it, use a web Api client (such as Postman) and run the following http request:\n\n```\nGET http://cloudservicename.cloudapp.net/WebApp/application/info\n```\n\nThe result should look like the following:\n\n```json\n{\n  \"Id\": \"WebApp\",\n  \"Version\": \"1.0.0\",\n  \"Yams Cluster Id\": \"MY_CLUSTER_ID\"\n}\n```\n\nSimilarly, you can deploy as many apps as you want by adding the corresponding binaries in the blob storage and the associated entries in the `DeploymentConfig.json` file.\n\n# Update a running app\nLet's update the web app and add a new coin flip Api to it. To do so:\n* Create a new `CoinFlipController`:\n\n```csharp\nusing System;\nusing System.Web.Http;\n\nnamespace WebApp\n{\n    [RoutePrefix(\"coinflip\")]\n    public class CoinFlipController : ApiController\n    {\n        private static readonly Random Random = new Random();\n\n        [HttpGet]\n        [Route(\"next\")]\n        public string Run()\n        {\n            if (Random.Next(2) == 0)\n            {\n                return \"Heads\";\n            }\n            return \"Tails\";\n        }\n    }\n}\n```\n\n* Build the project.\n* Upload the output of the build to the `applications/WebApp/1.1.0` blob directory.\n* Update the version number in the `DeploymentConfig.json` file to `1.1.0` (this step will trigger the update).\n\nThe new version of **WebApp** should be running in YAMS in less than a minute. To test it, run the following http requests:\n\n```\nGET http://cloudservicename.net/WebApp/application/info\nGET http://cloudservicename.net/WebApp/coinflip/next\n```\n\n# Running multiple versions of the same app side-by-side\n\nYAMS supports running multiple versions of the same app side-by-side. However, the app must be designed in a way that supports running multiple versions side-by-side. For instance, our current **WebApp** has not been designed with that in mind. In fact, if we try to run two versions of **WebApp** side-by-side, they will both try to use the same **url** and one of them will fail.\n\nTo fix this problem, let's add the **version** of the app to the url. To do so, go to the `Main` function and replace\n\n```csharp\nstring baseUrl = string.Format(\"http://{0}/{1}/\", GetIpAddress(), Id);\n```\n\nwith\n```csharp\n            Version version = new Version(Version);\n            string apiVersion = string.Format(\"{0}.{1}\", version.Major, version.Minor);\n            string baseUrl = string.Format(\"http://{0}/{1}/{2}\", GetIpAddress(), Id, apiVersion);\n```\n\nTo deploy the new version (let's say `2.0.0`) side-by-side with the currently running version (`1.1.0`), create and upload the `2.0.0` version as described in the previous section and add it to the `DeploymentConfig.json` file as follows:\n\n```json\n{\n\t\"Applications\":\n\t[\n\t\t{\n\t\t\t\"Id\": \"WebApp\",\n\t\t\t\"Version\": \"1.1.0\",\n\t\t\t\"TargetClusters\": [ \"MY_CLUSTER_ID\" ]\n\t\t},\n\t\t{\n\t\t\t\"Id\": \"WebApp\",\n\t\t\t\"Version\": \"2.0.0\",\n\t\t\t\"TargetClusters\": [ \"MY_CLUSTER_ID\" ]\n\t\t}\t\t\n\t]\n}\n```\n\nThat's it! The two versions should be now happily running side-by-side.\n\n# Removing or reverting a deployment\nTo remove an app from YAMS, simply remove the corresponding entry from the `DeploymentConfig.json` file. YAMS will terminate the corresponding process and remove the app. You can also delete the associated files from the blob storage if you are never going to use this app again or keep it there to preserve history of deployments and to allow reverts. In fact, to revert a deployment in YAMS, simply edit the `DeploymentConfig.json` file and replace the current version of the app (the version to be reverted) with the old version (the version to revert to).\n\n# Advanced features\n\nYams has support for health monitoring and graceful shutdown of apps as described [here](../Docs/Overview.md#health-monitoring-and-graceful-shutdown). Note that you can choose to enable one or multiple features and apps within the same cluster can use different features. \n\n## Monitored initialization\nBy default, Yams does not monitor the initialization of apps. In other words, when an app is deployed, the associated process is launched and then Yams assumes that the app is running and ready to receive requests. With the monitored initialization feature enabled, Yams would wait for the app to finish initialization before moving on to the next app (the app would notify Yams that it's done initializing through an IPC message).\n\nTo enable *monitored initialization* for a given app, the corresponding flag must be added to the `AppConfig.json` file as shown below:\n```json\n{\n  \"ExeName\": \"MyProcess.exe\",\n  \"ExeArgs\": \"Foo Bar\",\n  \"MonitorInitialization\": true\n}\n```\n\nThe app source code will also need to be updated so that the app can communicate with Yams (using IPC). Install the `Etg.Yams` NuGet package and modify the app source code so that Yams is notified when initialization is done, as shown in the code below:\n\n```csharp\n        public static void Main(string[] args)\n        {\n            MainAsync(args).Wait();\n        }\n\n        private static async Task MainAsync(string[] args)\n        {\n            var yamsClientConfig = new YamsClientConfigBuilder(args).Build();\n            var yamsClientFactory = new YamsClientFactory();\n            IYamsClient yamsClient = yamsClientFactory.CreateYamsClient(yamsClientConfig);\n\n            await Task.WhenAll(yamsClient.Connect(), Initialize());\n\n            await yamsClient.SendInitializationDoneMessage();\n\t    \n\t    // ...\n```\n\n## Heart beats\nWith this feature enabled, the app is expected to send heart beat messages to Yams at steady intervals. If heart beats are not received in time, errors will be logged (more complex handling will be added in the future). To enable this feature, update the `AppConfig.json` and your app source code as shown below:\n\n```json\n{\n  \"ExeName\": \"MyProcess.exe\",\n  \"ExeArgs\": \"Foo Bar\",\n  \"MonitorHealth\":  true\n}\n```\n\n```csharp\n        public static void Main(string[] args)\n        {\n            MainAsync(args).Wait();\n        }\n\n        private static async Task MainAsync(string[] args)\n        {\n            var yamsClientConfig = new YamsClientConfigBuilder(args).Build();\n            var yamsClientFactory = new YamsClientFactory();\n            IYamsClient yamsClient = yamsClientFactory.CreateYamsClient(yamsClientConfig);\n\n            await Task.WhenAll(yamsClient.Connect(), Initialize());\n\n            while (true)\n            {\n                await Task.Delay(heartBeatPeriod);\n                await yamsClient.SendHeartBeat();\n            }\n```\n\n## Graceful Shutdown\n\nWhen graceful shutdown is enabled for a given app, Yams will deliver an event to the app and allow it a configurable amount of time to exit gracefully before closing/killing it. The graceful shutdown event will be delivered through the `YamsClient` as a normal C# event. To enable this feature, update the `AppConfig.json` and your app source code as shown below:\n\n```json\n{\n  \"ExeName\": \"MyProcess.exe\",\n  \"ExeArgs\": \"Foo Bar\",\n  \"GracefulShutdown\":  true\n}\n```\n\n```csharp\n        public static void Main(string[] args)\n        {\n            MainAsync(args).Wait();\n        }\n\n        private static async Task MainAsync(string[] args)\n        {\n            var yamsClientConfig = new YamsClientConfigBuilder(args).Build();\n            var yamsClientFactory = new YamsClientFactory();\n            IYamsClient yamsClient = yamsClientFactory.CreateYamsClient(yamsClientConfig);\n\n            await Task.WhenAll(yamsClient.Connect(), Initialize());\n\n            bool exitMessageReceived = false;\n            yamsClient.ExitMessageReceived += (sender, eventArgs) =>\n            {\n                exitMessageReceived = true;\n            };\n\t    \n            while (!exitMessageReceived)\n            {\n                await DoWork();                \n            }\t    \n```\n\n# Source code\nThe source code associated with this tutorial can be found in the [Samples/WebApp](../Samples/WebApp) directory.\n"
  },
  {
    "path": "Docs/Deploy_Orleans_App_in_YAMS.md",
    "content": "# Overview\nIn this tutorial, we will explain how to create and deploy an Orleans application in YAMS. We will also explain how to connect to the Orleans application from a Web Api application.\n\n# Prerequisites\nYou must deploy YAMS using the multiple cluster sample in order to deploy Orleans applications. One cluster will be used for the client and one cluster will be used for the silos. It's recommended that you read the [Deploy and Host an App in YAMS tutorial](Deploy&Host_an_App_in_YAMS.md) before reading this tutorial. \n\n# Create the Orleans application\n\nFollow the *Hello World* tutorial described in Orleans [My First Orleans Application](http://dotnet.github.io/orleans/Step-by-step-Tutorials/My-First-Orleans-Application) to create a simple Orleans application that will be used in the rest of this tutorial.\n\nOnce you have the app ready, follow the steps below to deploy the app in YAMS:\n\n* Go to the **SiloHost** console application project and remove any client related code from the `Program.cs` file.\n* Open the `Program.cs` file and add the following code to configure the silo:\n\n```csharp\n        private static int StartSilo(string[] args)\n        {\n            // define the cluster configuration\n            var config = new ClusterConfiguration();\n            config.Globals.LivenessType = GlobalConfiguration.LivenessProviderType.AzureTable;\n            config.Globals.ReminderServiceType = GlobalConfiguration.ReminderServiceProviderType.AzureTable;\n            config.Globals.DataConnectionString = \"MY_DATA_CONNECTION_STRING\";\n            config.AddMemoryStorageProvider();\n            config.AddAzureTableStorageProvider(\"AzureStore\");\n            config.Defaults.DefaultTraceLevel = Severity.Error;\n            config.Defaults.Port = 100;\n            config.Defaults.ProxyGatewayEndpoint = new IPEndPoint(config.Defaults.Endpoint.Address, 101);\n\n            hostWrapper = new OrleansHostWrapper(config, args);\n            return hostWrapper.Run();\n        }\n```\n\n* Add the YAMS `AppConfig.json` file to the **SiloHost** project. The content of the `AppConfig.json` file is as follows:\n\n```json\n{\n    \"ExeName\": \"SiloHost.exe\",\n    \"ExeArgs\": \"deploymentid=${Id}_${Version.Major}.${Version.Minor}_${DeploymentId}\"\n}\n```\n\nThe argument for the `SiloHost.exe` executable is the Orleans deployment id for this application which must be the same across all role instances in the cloud service. In our case, the value of this argument will be resolved to `helloworld.orleans_1_0_MY_YAMS_BACKEND_CLUSTER_ID` and `MY_YAMS_BACKEND_CLUSTER_ID` will be a combination of the Cloud Service's deployment id and the Worker Role name. This deploymentId is used by Orleans to communicate between silos running on different role instances. It is also used by the client app (that we will describe later in this tutorial) to connect to the Orleans cluster.\n\n* In the `AppConfig.json` file properties, under \"Copy to Output Directory\", select either \"Copy Always\" or \"Copy if Newer\".\n\nNotice that we only used the major and minor versions (not the build version) in the silo name and the deploymentId. This will allow us to perform bug fixes to the silo and re-deploy it quickly using YAMS without affecting the clients of our app.\n\n* Finally, build the project and make sure that `SiloHost.exe` and `AppConfig.json` are copied to the build output directory and have the correct content.\n\n# Create the Orleans client application\nLet's now create a Web app that connects to the Orleans silo, calls the `HelloGrain.SayHello()` and prints the returned message to the output.\n\nFollow the [Deploy and Host an App in YAMS tutorial](Deploy&Host_an_App_in_YAMS.md) to create a Web app. To connect to the Orleans app from the web app, follow the steps below:\n\n* Install `Microsoft.Orleans.Client` NuGet package to the Web app project.\n* Install `Microsoft.Orleans.OrleansAzureUtils` NuGet package to the `SiloHost` console application project.\n* Add the following at the end of the `Main()` function (right before `Console.ReadLine()`):\n```csharp\n            var config = new ClientConfiguration();\n            config.GatewayProvider = ClientConfiguration.GatewayProviderType.AzureTable;\n            config.DeploymentId = \"hello.orleans_1.0_MY_YAMS_BACKEND_CLUSTER_ID\";\n            config.DataConnectionString = \"MY_DATA_CONNECTION_STRING\";\n            config.DefaultTraceLevel = Severity.Error;\n\n            // Attempt to connect a few times to overcome transient failures and to give the silo enough \n            // time to start up when starting at the same time as the client (useful when deploying or during development).\n\n            const int initializeAttemptsBeforeFailing = 5;\n\n            int attempt = 0;\n            while (true)\n            {\n                try\n                {\n                    GrainClient.Initialize(config);\n                    Console.WriteLine(\"Client initialized\");\n                    break;\n                }\n                catch (SiloUnavailableException e)\n                {\n                    attempt++;\n                    if (attempt >= initializeAttemptsBeforeFailing)\n                    {\n                        throw;\n                    }\n                    Thread.Sleep(TimeSpan.FromSeconds(2));\n                }\n            }\n```\n\nIt's **very important** that the `DeploymentId` and the `DataConnectionString` used above matches the ones that were used in the `helloworld.orleans` app.\n\n* Reference the Orleans interfaces project from the **WebApp** project.\n* Create an `OrleansHelloController` (see below) and add it to the **WebApp** project.\n\n```csharp\nnamespace WebApp\n{\n    [RoutePrefix(\"orleans\")]\n    public class OrleansHelloController : ApiController\n    {\n        [HttpGet]\n        [Route(\"hello\")]\n        public async Task<string> SayHello()\n        {\n            var helloGrain = GrainClient.GrainFactory.GetGrain<IHelloGrain>(0);\n            return await helloGrain.SayHello();\n        }\n    }\n}\n```\n\n* Add a `AppConfig.json` file to the **WebApp** project. The content of the `AppConfig.json` is as follows:\n\n```json\n{\n    \"ExeName\": \"WebApp.exe\",\n    \"ExeArgs\": \"${Id} ${Version} ${DeploymentId}\"\n}\n```\n\n* In the `AppConfig.json` file properties, under \"Copy to Output Directory\", select either \"Copy Always\" or \"Copy if Newer\".\n* Finally, build the project and make sure that `WebApp.exe` and `AppConfig.json` are copied to the build output directory and have the correct content.\n\n# Deploy the Orleans app and the web app to YAMS\nTo deploy both apps to YAMS follow the steps below:\n* Upload the build output of **OrleansHost** build output to the `applications/hello.orleans/1.0.0` blob directory.\n* Upload the build output of **WebApp** build output to the `applications/hello.webapp/1.0.0` blob directory.\n* Add the following content to the **DeploymentConfig.json** file:\n\n```json\n{\n\t\"Applications\":\n\t[\n\t\t{\n\t\t\t\"Id\": \"hello.orleans\",\n\t\t\t\"Version\": \"1.0.0\",\n\t\t\t\"TargetClusters\": [ \"MY_YAMS_BACKEND_CLUSTER_ID\" ]\n\t\t},\t\n\t\t{\n\t\t\t\"Id\": \"hello.webapp\",\n\t\t\t\"Version\": \"1.0.0\",\n\t\t\t\"TargetClusters\": [ \"MY_YAMS_FRONTEND_CLUSTER_ID\" ]\n\t\t},\t\t\t\n\t]\n}\n```\n\nGive YAMS some time to pick up the apps (typically less than a minute but in this case it'll probably take a bit longer because the Web app needs to connect to the Orleans silo) and run the following requests:\n\n```\nGET http://cloudservicename.cloudapp.net/hello.webapp/1.0/orleans/hello\n```\n\nYou should get the output below which indicates that both the Web App and the Orleans App are running in YAMS.\n```\n\"Hello World!\"\n```\n\n# Source code\nThe source code associated with this tutorial can be found in the [Samples/OrleansApp](../Samples/OrleansApp) directory.\n"
  },
  {
    "path": "Docs/Deploy_YAMS.md",
    "content": "# Overview\n\nThis tutorial will show you how to configure YAMS and deploy it to a cloud service. If you already have a YAMS cluster deployed, skip to [Deploy and Host an App in YAMS](Deploy&Host_an_App_in_YAMS.md) tutorial.\n\n## Deploy YAMS\n1. Create a cloud service and add a Worker Role to it.\n2. Install the latest version of `Etg.Yams` from the NuGet gallery to the worker role.\n3. Add the following private members to your `WorkerRoles.cs` class:\n\n```csharp\nprivate IYamsService _yamsService;\n\nprivate static string GetYamsClusterId()\n{\n    if (!RoleEnvironment.IsAvailable || RoleEnvironment.IsEmulated)\n    {\n        return \"testdeploymentid\";\n    }\n\n    return RoleEnvironment.DeploymentId;\n}\n```\n4. Replace the content of the `RunAsync` method with the following:\n\n```csharp\nprivate async Task RunAsync(CancellationToken cancellationToken)\n{\n    YamsConfig yamsConfig = new YamsConfigBuilder(\n        // mandatory configs\n        clusterId: GetYamsClusterId(),\n        instanceUpdateDomain: RoleEnvironment.CurrentRoleInstance.UpdateDomain.ToString(),\n        instanceId: RoleEnvironment.CurrentRoleInstance.Id,\n        applicationInstallDirectory: RoleEnvironment.GetLocalResource(\"LocalStoreDirectory\").RootPath)\n        // optional configs\n        .SetCheckForUpdatesPeriodInSeconds(5)\n        .SetApplicationRestartCount(3)\n        .Build();\n    _yamsService = YamsServiceFactory.Create(yamsConfig,\n        deploymentRepositoryStorageConnectionString: RoleEnvironment.GetConfigurationSettingValue(\"StorageDataConnectionString\"),\n        updateSessionStorageConnectionString: RoleEnvironment.GetConfigurationSettingValue(\"StorageDataConnectionString\"));\n\n    try\n    {\n        Trace.TraceInformation(\"Yams is starting\");\n        await _yamsService.Start();\n        Trace.TraceInformation(\"Yams has started. Looking for apps with clusterId:\" + GetYamsClusterId());\n    }\n    catch (Exception e)\n    {\n        Trace.TraceError($\"Failed to start the Yams cluster {GetYamsClusterId()}\", e);\n\treturn;\n    }\n\n    while (!cancellationToken.IsCancellationRequested)\n    {\n        await Task.Delay(1000);\n    }\n}\n```\n\n5. Add the following configuration to your `ServiceDefinition.csdef`\n\n```xml\n  <WorkerRole name=\"YamsWorkerRole\" vmsize=\"Small\">\n\n    <!-- Make sure that YAMS has elevated permissions -->\n    <Runtime executionContext=\"elevated\" />\n    \n    <ConfigurationSettings>\n      <!--blob storage connection string needed so that Yams can access the deployment storage -->\n      <Setting name=\"StorageDataConnectionString\" />\n    </ConfigurationSettings>\n\n    <LocalResources>\n      <!--Needed to tell Yams where to install apps -->\n      <LocalStorage name=\"LocalStoreDirectory\" cleanOnRoleRecycle=\"false\" />\n    </LocalResources>\n    \n  </WorkerRole>\n```\n\nDon't forget to add the corresponding values to your `ServiceConfiguration.Cloud.cscfg` and `ServiceConfiguration.Local.cscfg`\n\n6. Configure EndPoints to be used by YAMS apps\n\nTo allow applications to access endpoints, YAMS must register those endpoints in Azure when the cloud service containing YAMS is deployed. Fortunately, it is possible in Azure to register a range of endpoints. To do so, add the following to the **ServiceConfiguration.csdef** file:\n\n```xml\n    <Endpoints>\n      <InputEndpoint name=\"HttpsIn\" protocol=\"https\" port=\"443\" certificate=\"your-certificate.net\"/>\n      <InputEndpoint name=\"HttpIn\" protocol=\"http\" port=\"80\"/>\n      <InternalEndpoint name=\"TcpEndpoints\" protocol=\"tcp\">\n        <FixedPortRange min=\"81\" max=\"400\"/>\n      </InternalEndpoint>\n    </Endpoints>\n```\n\nIn this case, port 443 will be available for **https** connections, port 80 will be available for **http** connections and all ports from 81 to 400 will be open for **tcp** connections.\n\n\n7. Bind SSL Certificate\n\nIf you're using HTTPS, you probably want to bind an SSL certificate to your 443 port.\nTo Do so in your WorkerRole, simply add the following to your **ServiceConfiguration.csdef** file:\n\n```xml\n    </Certificates>\n    <Startup>\n      <Task commandLine=\"Scripts\\BindSSLCertificate.cmd\" executionContext=\"elevated\" taskType=\"simple\">\n        <Environment>\n          <Variable name=\"IsEmulated\">\n            <RoleInstanceValue xpath=\"/RoleEnvironment/Deployment/@emulated\" />\n          </Variable>\n        </Environment>\n      </Task>\n    </Startup>\n```\n\nThe corresponding script is shown below:\n\n```\nIF NOT DEFINED IsEmulated SET IsEmulated=false\nIF %IsEmulated%==true (\n    exit /b 0\n)\n\nnetsh http delete sslcert ipport=0.0.0.0:443\nnetsh http add sslcert ipport=0.0.0.0:443 appid={MY_APP_ID} certhash=MY_CERT_HASH\n```\nTo make sure the script is copied to your package, simply go to file properties in Visual Studio and set the `Copy to Output Directory` property to `Copy if newer` or `Copy always`.\n\n8. Publish the cloud service to Azure and start using YAMS. You should only need to publish the cloud service hosting YAMS once.\n\n## Deployment Storage\n\nYAMS relies on Azure blob storage to deploy applications. It uses the `dataConnectionString` provided in the `YamsConfig` to connect to the appropriate blob storage.\n\nYAMS expects to find a Storage Container called `applications` at the root of the blob storage. The `applications` container must contain a **DeploymentConfig.json** file that describes the applications to be deployed. The **DeploymentConfig.json** file looks like the following:\n\n```json\n{\n\t\"Applications\":\n\t[\n        {\n            \"Id\": \"hello.webapi\",\n            \"Version\": \"1.0.1\",\n            \"TargetClusters\": [ \"YAMS_CLUSTER_ID\" ]\n        },\t\n\t\t{\n            \"Id\": \"hello.backend\",\n\t\t\t\"Version\": \"1.0.0\",\n            \"TargetClusters\": [ \"YAMS_CLUSTER_ID\" ]\n\t\t},\n\t]\n}\n```\n\nIn this case, the application `hello.webapi`, version `1.0.1` will be deployed to the cloud service with deployment Id *\"YAMS_CLUSTER_ID\"*. The binaries of the application should be available in the blob storage at the path `applications/hello.webapi/1.0.1`.\n\nThe blob storage content in the example above will look as follows:\n\n```\napplications\n|___ hello.backend\n|   |___ 1.0.0\n|___ hello.webapi\n|   |___ 1.0.1\n|___ DeploymentConfig.json            \n```\n\nYAMS will download all the applications in the blob storage (that are listed in the **DeploymentConfig.json** file) to each role instance of the cloud service and start the applications on all instances. To start an application, YAMS reads the **AppConfig.json** (that must be available at the root of each application) to figure out the **exe** name and arguments for that specific application.\n\nThe **AppConfig.json** file looks as follows:\n\n```json\n{\n    \"ExeName\": \"WebApiHost.exe\",\n    \"ExeArgs\": \"-p Https --appName=${Id}\"\n}\n```\n\nIn this case, YAMS will use the following command to start the application:\n\n```\nWebApiHost.exe -p Https --appName=hello.webapi\n```\n\nNotice the `${Id}` symbol in the `ExeArgs` that was substituted with the actual **id** of the application. Other available symbols are (symbols are resolved at runtime by YAMS):\n* ${Version}\n* ${Version.Major}\n* ${Version.Minor}\n* ${Version.Build}\n* ${DeploymentId}: the cloud service deployment id.\n* ${InstanceId}: the current role instance id.\n"
  },
  {
    "path": "Docs/Overview.md",
    "content": "# YAMS Overview\n\nThe [Microsoft Azure cloud services](https://azure.microsoft.com/en-us/services/cloud-services/) platform allows developers to deploy and host highly available, reliable and scalable microservices and applications in the cloud. The platform handles creating and managing VMs, load balancing, scaling (and auto-scaling), Virtual IP (VIP) swap and more.\n\nTypically, an application is first deployed to a staging environment for testing. If testing is successful, the application is promoted to the production environment by performing a VIP swap. With each environment (e.g. staging and production) is associated at least one VM where the application will be running. For real world applications, several VMs are usually needed to handle traffic.\n\nA microservices-based application is usually composed of a large number of microservices. Each microservice can be independently deployed, hosted, scaled and versioned. Microservices within the same application are loosely coupled and communicate with each other via HTTP / REST. As a result, microservices within the same application can also be developed in different programming languages.\n\nTo deploy such a Microservices-based application to Azure using the Azure cloud services platform, a cloud service is needed to deploy and host each microservice. Given that each cloud service requires at least one VM (usually more), the cost can quickly become unreasonable for a large number of microservices.\n\n**YAMS** (Yet Another Microservices Solution) is a library that can be used to deploy and host microservices on premises, in Azure, or on other cloud service platforms. It offers the following features:\n* **Quick deployments** of microservices to any target environment (~1 minute deployments to Azure). \n* **Sharing infrastructure** (multiple microservices can be deployed to the same on premises or cloud service). \n* **Scaling microservices independently**.\n* **Versioning** of microservices, quick **updates**, **reverts**, etc. \n* Support for **Upgrade Domains** to minimize (and potentially eliminate) application downtime during updates, including first-class support for **Azure Upgrade Domains**.\n* Microservices can be developed in **any programming language** and deployed with YAMS (as long as your service can be started with an exe).\n* **Health monitoring** and **graceful shutdown** of microservices.\n\nYAMS has first-class support for deploying applications from Azure **blob storage**, but with its pluggable storage architecture, other providers such as SQL Server or file storage can be created and plugged in as well. \n\nTo deploy an application to a YAMS cluster, simply drop the binaries of the application into YAMS storage. The binaries are then picked-up by YAMS, deployed to all VMs in the cluster, and then launched.\n\n# How does it work?\nYams itself is deployed either as a cloud service to Azure, on another cloud service platform, or on premises (we call it a Yams cluster). A Yams cluster is associated with a deployment storage (e.g. blob storage) where the binaries of microservices are deployed (note that *microservices* in Yams are often referred to as *applications* or simply *apps*). Yams periodically scans its deployment storage for updates. \n\n## The deployment storage structure\nThe *applications* in deployment storage can be organized with the following structure:\n\n```\napplications\n|___ app1\n|   |___ 1.0.0\n|___ app2\n|   |___ 1.0.0\n|   |___ 1.0.1\n|___ DeploymentConfig.json \n```\n\nDepending on what kind of storage provider is being used, these could be folders in a blob- or file-system-based deployment storage provider, columns in a relational database table, etc.\n\nThe `DeploymentConfig.json` file contains information about what application should be deployed and where. It has the following structure:\n```json\n{\n    \"Applications\":\n    [\n        {\n            \"Id\": \"app1\",\n            \"Version\": \"1.0.0\",\n            \"TargetClusters\": [ \"YAMS_CLUSTER_ID\" ]\n        },  \n        {\n            \"Id\": \"app2\",\n            \"Version\": \"1.0.1\",\n            \"TargetClusters\": [ \"YAMS_CLUSTER_ID\", \"YAMS_CLUSTER_ID_OTHER\" ]\n        },\n    ]\n}\n```\n\nThe `TargetClusters` field identifies the Yams clusters where an application should be deployed.\n\n## Deploying Yams to a cloud service\nYams can be deployed to Azure like any typical cloud service. The [Deploy YAMS tutorial](Deploy_YAMS.md) explains the steps needed to deploy Yams to Azure.\n\n## Scanning blob storage\nWhen a Yams cluster is deployed to a cloud service, each instance in the cluster reads the `DeploymentConfig.json` file and deploy all apps that have the corresponding `ClusterId` (typically the deployment id of the cloud service where the Yams cluster is deployed). Then, periodically, each Yams instance scans the `DeploymentConfig.json` file for changes and takes the appropriate actions. There are three types of changes that can occur:\n\n1. **An application is added** \n2. **An application is removed**\n3. **An application is updated**\n\nNote that the operations described below can be performed using Yams Powershell interface. Yams Powerhsell cmdlets are available [here](../src/Etg.Yams.Powershell) and can be downloaded using the NuGet package [Etg.Yams.Powershell](https://www.nuget.org/packages/Etg.Yams.Powershell/).\n\n### Adding an application\nThis occurs when a new application or a new version of an application is added to the `DeploymentConfig.json` file. Each Yams instance downloads the app's binaries to the VM where it's running and starts the application using the exe available with the binaries. In fact, each Yams application (i.e. microservice) contains an `AppConfig.json` file that describes how the application can be started. The `AppConfig.json` file has the following structure:\n```json\n{\n    \"ExeName\": \"Foo.exe\",\n    \"ExeArgs\": \"--appName=${Id} --arg2 10\"\n}\n```\n\nNotice the ${Id} variable in the ExeArgs which will be substituted with the actual id of the application at runtime. Other available variables are:\n\n* ${Version}\n* ${Version.Major}\n* ${Version.Minor}\n* ${Version.Build}\n* ${ClusterId}: the Yams cluster id.\n* ${InstanceId}: the current VM instance id.\n\nYou can also pass custom variables to Yams using two ways:\n1. Add properties to your cluster at startup:\n\n```csharp\n            YamsConfig yamsConfig = new YamsConfigBuilder(\n                // mandatory configs\n                clusterId: clusterId,\n                instanceUpdateDomain: RoleEnvironment.CurrentRoleInstance.UpdateDomain.ToString(),\n                instanceId: RoleEnvironment.CurrentRoleInstance.Id,\n                applicationInstallDirectory: RoleEnvironment.GetLocalResource(\"LocalStoreDirectory\").RootPath)\n                // optional configs\n                .AddClusterProperty(\"EnvironmentName\", RoleEnvironment.GetConfigurationSettingValue(\"EnvironmentName\"))\n                .AddClusterProperty(\"DeploymentId\", GetDeploymentId())\n                .Build();\n```\nProperties added using `AddClusterProperty` will be available to all apps. The drawback of this approach is that it requires a cluster restart to add new properties. The second approach below only requires modifying the `DeploymentConfig.json`.\n\n2. Add cluster properties to your app in the `DeploymentConfig.json` (this can be done using `Install-Applications` Powershell cmdlet):\n\n```json\n{\n    \"Applications\":\n    [\n        {\n            \"Id\": \"app1\",\n            \"Version\": \"1.0.0\",\n            \"TargetClusters\": [ \"YAMS_CLUSTER_ID\" ],\n            \"Properties\":\n            {\n                \"EnvironmentName\": \"Dev\"\n            }            \n        },  \n        {\n            \"Id\": \"app2\",\n            \"Version\": \"1.0.1\",\n            \"TargetClusters\": [ \"YAMS_CLUSTER_ID\", \"YAMS_CLUSTER_ID_OTHER\" ],\n            \"Properties\":\n            {\n                \"EnvironmentName\": \"Dev\"\n            }               \n        },\n    ]\n}\n```\n\nNote that Yams supports running multiple versions of the same app side-by-side. Please see the [Deploy and Host an App in YAMS tutorial](Deploy&Host_an_App_in_YAMS.md) to learn more about this feature.\n\n### Removing an application\nThis occurs when an application or a version of an application is removed from the the `DeploymentConfig.json` file. Each Yams instance terminates the process associated with the application.\n\n### Updating an application\nThis occurs when the version of an existing application has changed in the `DeploymentConfig.json` file (this includes upgrades and downgrades). Each Yams instance removes the old version of the application and then adds the new version.\n\nYams supports **Azure Upgrade Domains** to minimize (and potentially eliminate) application downtime during updates. In fact, each Yams instance (VM) in the Yams cluster is associated with an **upgrade domain** and only VMs with the same upgrade domain can be updated simultaneously. When a Yams instance attempts to update an application, it checks first if the application is being updated on another Yams instance with a different upgrade domain. If that's the case, the Yams instance discards the update and attempts again at the next blob storage scan; until it eventually performs the update.\n\nNote that if an update fails, Yams will not try to revert back to the old version. However, Yams will keep trying to perform the update at every cycle (every time it checks for updates) and will log errors if the installation fails. Yams uses `System.Diagnostics.Trace` to log errors which can be re-routed to blob storage or other locations by configuring the appropriate trace listener.\n\nTo revert a deployment, simply edit the `DeploymentConfig.json` file and replace the current version of the app (the version to be reverted) with the old version (the version to revert to).\n\n## Monitoring YAMS Deployments\n\nSimilarly to the `DeploymentConfig.json` blob that instructs YAMS on what applications to deploy, YAMS exposes status blobs that expose the current status of the YAMS cluster to the outside world (for monitoring and visualization purposes).\n\nWhen using blob storage, the deployment status blobs are published at:\n\n```\napplications/status/clusters/clusterName/instances/\n```\n\nThe blob storage deployment repository looks as follows:\n```\napplications\n|___ app1\n|   |___ 1.0.0\n|___ app2\n|   |___ 1.0.1\n|\n|___ DeploymentConfig.json \n|\n|___ status\n|   |___ clusters\n|       |___ clusterName\n|           |___ instances\n|               |___ instance_1\n|               |___ instance_2\n|               |___ ...\n|               |___ instance_n\n```\n\n`instance_i` is the id of a given node in the cluster (aka instance id). The instance id is chosen when YAMS itself is deployed (e.g. when using a cloud service to deploy YAMS, the instance ids from the cloud service are passed down to YAMS). The content of the `instance_i` blob is as follows:\n\n```json\n{\n  \"Applications\": [\n    {\n      \"Id\": \"app1\",\n      \"Version\": \"1.0.0\",\n      \"ClusterId\": \"MY_CLUSTER_ID\",\n      \"InstanceId\": \"instance_i\",\n      \"UtcTimeStamp\": \"2017-10-13T02:48:17.0168224Z\"\n    },\n    {\n      \"Id\": \"app2\",\n      \"Version\": \"1.0.1\",\n      \"ClusterId\": \"MY_CLUSTER_ID\",\n      \"InstanceId\": \"instance_i\",\n      \"UtcTimeStamp\": \"2017-10-13T02:48:17.0168224Z\"\n    }    \n  ]\n}\n```\n\nThe above instance status confirms that the listed applications are currently running in the YAMS cluster as of `UtcTimeStamp`. The `UtcTimeStamp` is updated by YAMS every time YAMS checks for updates (default is 5 seconds).\n* The `UtcTimeStamp` is updated periodically even if the app has not been updated.\n* If an app is removed from the cluster, it will removed from the instance status blob.\n* If the `UtcTimeStamp` corresponding to a given app is old, it's an indication that the YAMS instance is experiencing issues.\n* Usually, all `UtcTimeStamp` values in the blob corresponding to a given instance are equal.\n\nIn addition to providing information about the status of the cluster, the deployment status blob can be used to monitor the health of YAMS nodes.\n\nAnother main use case of the deployment status feature is to allow continueous deployment tools (e.g. VSTS) to ensure that the new version of a given application is up and running before finishing the deployment.\n\nThe deployment status can be accessed using Powershell as follows:\n\n```powershell\nGet-DeploymentStatus -ConnectionString \"MyConnectionString\"\n```\n\n## Health monitoring of applications and graceful shutdown\n\nApps deployed with Yams can optionally enable health monitoring and/or graceful shutdown. Yams uses inter-process-communication (currently [named pipes](https://msdn.microsoft.com/en-us/library/bb546085(v=vs.110).aspx)) to communicate with apps. \n\nThere are three features available:\n* *Monitored initialization*: Yams waits for the app to finish initialization before considering it ready to receive requests. If an app takes longer than expected to finish initialization (the timeout is configurable), it's considered unhealthy and is killed.\n* *Monitored heart beats*: With this feature enabled, Yams expects to receive heart beats from apps at steady intervals. If a heart beat is not received in time, an error is logged (more complex handling will be added in the future).\n* *Graceful shutdown*: A event is sent to the app to signal shutdown. If the app does not exit gracefully in time (the timeout is configurable), the app will be closed or killed.\n\nNote that each of these features can be enabled/disabled separately. In addition, apps running within the same cluster can choose to enable/disable different features.\n\nThe [Yams Client API](../src/Etg.Yams.Client/IYamsClient.cs) can be used by apps to communicate with Yams. See [Deploy and host applications in YAMS tutorial](../Docs/Deploy&Host_an_App_in_YAMS.md) to learn how you can enable these features (one ore more features can be enabled at a time).\n\n## Sharing infrastructure\nOne of the main goals of Yams is sharing infrastructure to reduce cost. In fact, some microservices consume little resources and can be deployed alongside other microservices. In addition, sharing infrastructure reduces the cost of over-provisioning resources. To illustrate this, consider an application composed of two microservices. Each microservice requires 2 VMs at normal operation load and 4 VMs at peak time. If each microservice is deployed separately, 8 VMs are needed in total (4 VMs per microservice). However, in practice, the peak time resources are over estimated and the peak time of one microservice does not necessarily overlap with the peak time of another microservice. If the same VMs are shared by both microservices and peak times are not likely to overlap, 6 VMs can be sufficient for both microservices (which saves us 2 VMs). In fact, this strategy works better for a large number of microservices where the probability of all microservices peaking at the same time decreases with the number of microservices and as a result, sharing infrastructure can result in large savings.\n\nAnother use case where sharing infrastructure can result in large savings is in testing environments. In fact, without sharing infrastructure, at least one additional VM is needed for testing each microservice. Considering that testing (such as running integration and end to end tests) doesn't have high performance requirements and that microservices are not all tested at the same time, using a pool of shared VMs for testing can significantly reduce the number of required VMs.\n\nTo deploy multiple apps to the same Yams cluster, simply use the same cluster id as shown below:\n```\n{\n    \"Applications\":\n    [\n        {\n            \"Id\": \"app1\",\n            \"Version\": \"1.0.0\",\n            \"TargetClusters\": [ \"cluster_1_id\" ]\n        },  \n        {\n            \"Id\": \"app2\",\n            \"Version\": \"1.0.1\",\n            \"TargetClusters\": [ \"cluster_1_id\" ]\n        },\n    ]\n}\n```\n\n### Scaling microservices independently\nEven though sharing VMs can result in large cost savings, the number of microservices that can coexist on the same VM is limited due to memory constraints. In fact, if a pool of VMs is shared by several microservices, each VM must have a total amount of memory that is the sum of the amounts of memory required for each microservice. Obviously, this doesn't scale very well.\n\nTo address this issue, microservices can be deployed to different Yams clusters depending on the requirements of each microservice. In the following example, `Microservice1` requires a dedicated VM while `Microservice2` and `Microservice3` can be deployed to the same VM. \n```\n{\n    \"Applications\":\n    [\n        {\n            \"Id\": \"Microservice1\",\n            \"Version\": \"1.0.0\",\n            \"TargetClusters\": [ \"cluster_1_id\" ]\n        },  \n        {\n            \"Id\": \"Microservice2\",\n            \"Version\": \"1.0.1\",\n            \"TargetClusters\": [ \"cluster_2_id\" ]\n        },\n        {\n            \"Id\": \"Microservice3\",\n            \"Version\": \"2.0.0\",\n            \"TargetClusters\": [ \"cluster_2_id\" ]\n        },        \n    ]\n}\n```\n\nIn the above case, CPU resources needed for `Microservice2` and `Microservice3` are scaled together (by scaling the number of VMs in cluster 2) while `Microservice1` is scaled independently (cluster 1). \n"
  },
  {
    "path": "Docs/YAMS_Storage.md",
    "content": "# YAMS Storage Tutorial\n\nThis tutorial demonstrates the use of the `IDeploymentRepository` Api which can be used to fully control the Yams Storage. It provides capabilities such as downloading and uploading of application binaries, and the manipulation of the `DeploymentConfig.json` file. In fact, the Api completely decouples users from Blob storage and from the `DeploymentConfig.json` content and format.\n\n* Create a proxy to the Yams storage\n```csharp\n    IDeploymentRepository deploymentRepository = BlobStorageDeploymentRepository.Create(\"my_data_connection_string\");\n```\n\n* Fetch the DeploymentConfig\n```csharp\n\tDeploymentConfig deploymentConfig = await deploymentRepository.FetchDeploymentConfig();\n\t\n\t// DeploymentConfig implements IEnumerable.\n\tforeach(AppDeploymentConfig appDeploymentConfig in deploymentConfig)\n\t{\n\t\tAppIdentity appIdentity = appDeploymentConfig.AppIdentity;\n\t\tIEnumerable<string> targetClusters = appDeploymentConfig.TargetClusters;\n\t}\t\n```\n\n* Deploy a new application\n```csharp\n\tAppIdentity appIdentity = new AppIdentity(\"AppId\", \"1.0.0\");\n\n\t// Upload the application binaries\n\tawait deploymentRepository.UploadApplicationBinaries(appIdentity, localBinariesDirPath, ConflictResolutionMode.FailIfBinariesExist);\n\n\t// Update the DeploymentConfig. Note that the DeploymentConfig class is immutable\n\tDeploymentConfig deploymentConfig = await deploymentRepository.FetchDeploymentConfig();\n\tdeploymentConfig = deploymentConfig.AddApplication(appIdentity, \"yams_cluster_id\");\n\n\t// The application will only be deployed to the cluster when the DeploymentConfig is published\n\tawait deploymentRepository.PublishDeploymentConfig(deploymentConfig);\n```\n\n* Update an application\n\n```csharp\n\t// Upload the new binaries\n\tawait deploymentRepository.UploadApplicationBinaries(newAppIdentity, localBinariesDirPath, ConflictResolutionMode.FailIfBinariesExist);\n\n\t// Fetch and update the DeploymentConfig\n\tDeploymentConfig deploymentConfig = await deploymentRepository.FetchDeploymentConfig();\n\tdeploymentConfig = deploymentConfig.RemoveApplication(oldAppIdentity, \"yams_cluster_id\");\n\tdeploymentConfig = deploymentConfig.AddApplication(newAppIdentity, \"yams_cluster_id\");\n\n\t// The update will be performed when the new DeploymentConfig is published\n\tawait deploymentRepository.PublishDeploymentConfig(deploymentConfig);\n\n\t// You can also cleanup the old binaries if you're not planing to revert back to it in the future.\n\tawait deploymentRepository.DeleteApplicationBinaries(oldAppIdentity);\n```\n\n* Remove an application\n```csharp\n    // Update the DeploymentConfig\n    DeploymentConfig deploymentConfig = await deploymentRepository.FetchDeploymentConfig();\n\n    // Remove the app from the DeploymentConfig\n    deploymentConfig = deploymentConfig.RemoveApplication(appIdentity, \"yams_cluster_id\");\n\n    // The app will be shutdown when the DeploymentConfig is published\n    await deploymentRepository.PublishDeploymentConfig(deploymentConfig);\n\n    // You can also cleanup the old binaries if you're not planing to revert back to it in the future.\n    await deploymentRepository.DeleteApplicationBinaries(appIdentity);\n```\n\n* Other DeploymentConfig Apis\n```csharp\n    // Get the list of apps Ids\n    IEnumerable<string> appIds = deploymentConfig.ListApplications();\n\n    // Get the list of applications deployed to a given yams cluster\n    appIds = deploymentConfig.ListApplications(\"yams_cluster_id\");\n\n    // Get the list of versions of a given app\n    IEnumerable<string> versions = deploymentConfig.ListVersions(\"MyAppId\");\n\n    // Get the list of versions of a given app that are deployed on a given Yams cluster\n    versions = deploymentConfig.ListVersions(\"myAppId\", \"yams_cluster_id\");\n\n    // List the yams clusters where an app is deployed\n    IEnumerable<string> clusterIds = deploymentConfig.ListClusters(\"MyAppId\");\n\n    // List the yams clusters where a version of an app is deployed\n    clusterIds = deploymentConfig.ListClusters(new AppIdentity(\"MyAppId\", \"1.0.0\"));\n\n    // Add a application to the DeploymentConfig.json\n    deploymentConfig.AddApplication(new AppIdentity(\"AppId\", \"2.0.0\"), \"yams_cluster_id\");\n\n    // Remove an application, a specific version or a specific cluster:\n    deploymentConfig.RemoveApplication(\"MyAppId\");\n    deploymentConfig.RemoveApplication(new AppIdentity(\"MyAppId\", \"1.0.0\"));\n    deploymentConfig.RemoveApplication(new AppIdentity(\"MyAppId\", \"1.0.0\"), \"yams_cluster_id\");\n```\n"
  },
  {
    "path": "Etg.Yams.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.26730.12\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams\", \"src\\Etg.Yams\\Etg.Yams.csproj\", \"{E1A6854F-6C0D-4F93-9B8D-D6981727D15B}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Test\", \"Test\", \"{2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"AzureTestUtils\", \"test\\AzureTestUtils\\AzureTestUtils.csproj\", \"{84C08621-2C78-4B19-9454-7B9019E68326}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"HangingProcess\", \"test\\HangingProcess\\HangingProcess.csproj\", \"{1DD27CAF-AC19-4674-A42B-F15260929BAF}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"SuicidalProcess\", \"test\\SuicidalProcess\\SuicidalProcess.csproj\", \"{80A3B3BD-8D2F-471A-A198-576772FAA048}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"TestProcess\", \"test\\TestProcess\\TestProcess.csproj\", \"{AEAEE225-1080-4CC9-8BA8-9F7580ED1B9B}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams.Core.Test\", \"test\\Etg.Yams.Core.Test\\Etg.Yams.Core.Test.csproj\", \"{98B0AE89-5D42-4366-9C0E-9392737E36AC}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"source\", \"source\", \"{5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"AzureBlobStorageDeploymentRepository\", \"src\\AzureBlobStorageDeploymentRepository\\AzureBlobStorageDeploymentRepository.csproj\", \"{DF95A9DC-F6BE-4C71-B444-4092B43EB602}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Common\", \"src\\Common\\Common.csproj\", \"{3E982150-5B43-44DA-8D96-66CF07A9A14C}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"AzureUtils\", \"src\\AzureUtils\\AzureUtils.csproj\", \"{1C890E49-5A9B-4EAB-9F69-6A6E78D82610}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"AzureBlobStorageUpdateSession\", \"src\\AzureBlobStorageUpdateSession\\AzureBlobStorageUpdateSession.csproj\", \"{894B7986-5AA4-42A7-8EB0-6DFD1F604505}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"AzureBlobStorageUpdateSessionTest\", \"test\\AzureBlobStorageUpdateSessionTest\\AzureBlobStorageUpdateSessionTest.csproj\", \"{9C0602C2-00DD-43F4-B274-6598AF33C00A}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"TestUtils\", \"test\\TestUtils\\TestUtils.csproj\", \"{C25452E1-AFF2-4579-B6B4-F040CAD02FDA}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"AzureBlobStorageDeploymentRepositoryTest\", \"test\\AzureBlobStorageDeploymentRepositoryTest\\AzureBlobStorageDeploymentRepositoryTest.csproj\", \"{E66F281C-BD50-45B0-AAEF-FB87E4C9D0CC}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"AzureUtilsTest\", \"test\\AzureUtilsTest\\AzureUtilsTest.csproj\", \"{2FE963BD-D826-4CC5-8A63-864CDA212233}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams.Core\", \"src\\Etg.Yams.Core\\Etg.Yams.Core.csproj\", \"{7145E485-34FA-4632-89B0-BD27C96AF69C}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Stubs\", \"test\\Stubs\\Stubs.csproj\", \"{68CD41F8-A6C3-4D43-93CA-92E898254CBD}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"MonitorInitProcess\", \"test\\MonitorInitProcess\\MonitorInitProcess.csproj\", \"{BB84CC4C-EB11-4A61-8ED4-791EADAA46E1}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"GracefullShutdownProcess\", \"test\\GracefullShutdownProcess\\GracefullShutdownProcess.csproj\", \"{706E37D7-B148-4734-9695-0D1AE6D4B3D5}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"HeartBeatProcess\", \"test\\HeartBeatProcess\\HeartBeatProcess.csproj\", \"{257044FB-F7A8-499D-8EF2-B5CAD76D617A}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"FullIpcProcess\", \"test\\FullIpcProcess\\FullIpcProcess.csproj\", \"{99F3A36C-7930-4670-A8B3-7137D891671D}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams.Powershell\", \"src\\Etg.Yams.Powershell\\Etg.Yams.Powershell.csproj\", \"{CDFBE3EE-AFD7-467F-BE9C-F9EAFC7A05CE}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams.Client\", \"src\\Etg.Yams.Client\\Etg.Yams.Client.csproj\", \"{D4624B9B-67A1-46D5-9468-58995B2720F9}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams.Ipc\", \"src\\Etg.Yams.Ipc\\Etg.Yams.Ipc.csproj\", \"{C7C03D37-F2D2-4115-8423-86C1BF1B8A18}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams.Host\", \"src\\Etg.Yams.Host\\Etg.Yams.Host.csproj\", \"{C9A993F7-E3E2-4FDC-AA1E-01348B023D16}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{E1A6854F-6C0D-4F93-9B8D-D6981727D15B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E1A6854F-6C0D-4F93-9B8D-D6981727D15B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E1A6854F-6C0D-4F93-9B8D-D6981727D15B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E1A6854F-6C0D-4F93-9B8D-D6981727D15B}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{84C08621-2C78-4B19-9454-7B9019E68326}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{84C08621-2C78-4B19-9454-7B9019E68326}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{84C08621-2C78-4B19-9454-7B9019E68326}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{84C08621-2C78-4B19-9454-7B9019E68326}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{1DD27CAF-AC19-4674-A42B-F15260929BAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{1DD27CAF-AC19-4674-A42B-F15260929BAF}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{1DD27CAF-AC19-4674-A42B-F15260929BAF}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{1DD27CAF-AC19-4674-A42B-F15260929BAF}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{80A3B3BD-8D2F-471A-A198-576772FAA048}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{80A3B3BD-8D2F-471A-A198-576772FAA048}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{80A3B3BD-8D2F-471A-A198-576772FAA048}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{80A3B3BD-8D2F-471A-A198-576772FAA048}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{AEAEE225-1080-4CC9-8BA8-9F7580ED1B9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{AEAEE225-1080-4CC9-8BA8-9F7580ED1B9B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{AEAEE225-1080-4CC9-8BA8-9F7580ED1B9B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{AEAEE225-1080-4CC9-8BA8-9F7580ED1B9B}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{98B0AE89-5D42-4366-9C0E-9392737E36AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{98B0AE89-5D42-4366-9C0E-9392737E36AC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{98B0AE89-5D42-4366-9C0E-9392737E36AC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{98B0AE89-5D42-4366-9C0E-9392737E36AC}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{DF95A9DC-F6BE-4C71-B444-4092B43EB602}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{DF95A9DC-F6BE-4C71-B444-4092B43EB602}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{DF95A9DC-F6BE-4C71-B444-4092B43EB602}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{DF95A9DC-F6BE-4C71-B444-4092B43EB602}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{3E982150-5B43-44DA-8D96-66CF07A9A14C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{3E982150-5B43-44DA-8D96-66CF07A9A14C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{3E982150-5B43-44DA-8D96-66CF07A9A14C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{3E982150-5B43-44DA-8D96-66CF07A9A14C}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{1C890E49-5A9B-4EAB-9F69-6A6E78D82610}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{1C890E49-5A9B-4EAB-9F69-6A6E78D82610}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{1C890E49-5A9B-4EAB-9F69-6A6E78D82610}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{1C890E49-5A9B-4EAB-9F69-6A6E78D82610}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{894B7986-5AA4-42A7-8EB0-6DFD1F604505}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{894B7986-5AA4-42A7-8EB0-6DFD1F604505}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{894B7986-5AA4-42A7-8EB0-6DFD1F604505}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{894B7986-5AA4-42A7-8EB0-6DFD1F604505}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{9C0602C2-00DD-43F4-B274-6598AF33C00A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{9C0602C2-00DD-43F4-B274-6598AF33C00A}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{9C0602C2-00DD-43F4-B274-6598AF33C00A}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{9C0602C2-00DD-43F4-B274-6598AF33C00A}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C25452E1-AFF2-4579-B6B4-F040CAD02FDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C25452E1-AFF2-4579-B6B4-F040CAD02FDA}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C25452E1-AFF2-4579-B6B4-F040CAD02FDA}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C25452E1-AFF2-4579-B6B4-F040CAD02FDA}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{E66F281C-BD50-45B0-AAEF-FB87E4C9D0CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E66F281C-BD50-45B0-AAEF-FB87E4C9D0CC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E66F281C-BD50-45B0-AAEF-FB87E4C9D0CC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E66F281C-BD50-45B0-AAEF-FB87E4C9D0CC}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{2FE963BD-D826-4CC5-8A63-864CDA212233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{2FE963BD-D826-4CC5-8A63-864CDA212233}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{2FE963BD-D826-4CC5-8A63-864CDA212233}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{2FE963BD-D826-4CC5-8A63-864CDA212233}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{7145E485-34FA-4632-89B0-BD27C96AF69C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{7145E485-34FA-4632-89B0-BD27C96AF69C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{7145E485-34FA-4632-89B0-BD27C96AF69C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{7145E485-34FA-4632-89B0-BD27C96AF69C}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{68CD41F8-A6C3-4D43-93CA-92E898254CBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{68CD41F8-A6C3-4D43-93CA-92E898254CBD}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{68CD41F8-A6C3-4D43-93CA-92E898254CBD}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{68CD41F8-A6C3-4D43-93CA-92E898254CBD}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BB84CC4C-EB11-4A61-8ED4-791EADAA46E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BB84CC4C-EB11-4A61-8ED4-791EADAA46E1}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BB84CC4C-EB11-4A61-8ED4-791EADAA46E1}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BB84CC4C-EB11-4A61-8ED4-791EADAA46E1}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{706E37D7-B148-4734-9695-0D1AE6D4B3D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{706E37D7-B148-4734-9695-0D1AE6D4B3D5}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{706E37D7-B148-4734-9695-0D1AE6D4B3D5}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{706E37D7-B148-4734-9695-0D1AE6D4B3D5}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{257044FB-F7A8-499D-8EF2-B5CAD76D617A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{257044FB-F7A8-499D-8EF2-B5CAD76D617A}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{257044FB-F7A8-499D-8EF2-B5CAD76D617A}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{257044FB-F7A8-499D-8EF2-B5CAD76D617A}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{99F3A36C-7930-4670-A8B3-7137D891671D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{99F3A36C-7930-4670-A8B3-7137D891671D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{99F3A36C-7930-4670-A8B3-7137D891671D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{99F3A36C-7930-4670-A8B3-7137D891671D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{CDFBE3EE-AFD7-467F-BE9C-F9EAFC7A05CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{CDFBE3EE-AFD7-467F-BE9C-F9EAFC7A05CE}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{CDFBE3EE-AFD7-467F-BE9C-F9EAFC7A05CE}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{CDFBE3EE-AFD7-467F-BE9C-F9EAFC7A05CE}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{D4624B9B-67A1-46D5-9468-58995B2720F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{D4624B9B-67A1-46D5-9468-58995B2720F9}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{D4624B9B-67A1-46D5-9468-58995B2720F9}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{D4624B9B-67A1-46D5-9468-58995B2720F9}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C7C03D37-F2D2-4115-8423-86C1BF1B8A18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C7C03D37-F2D2-4115-8423-86C1BF1B8A18}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C7C03D37-F2D2-4115-8423-86C1BF1B8A18}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C7C03D37-F2D2-4115-8423-86C1BF1B8A18}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C9A993F7-E3E2-4FDC-AA1E-01348B023D16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C9A993F7-E3E2-4FDC-AA1E-01348B023D16}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C9A993F7-E3E2-4FDC-AA1E-01348B023D16}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C9A993F7-E3E2-4FDC-AA1E-01348B023D16}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{E1A6854F-6C0D-4F93-9B8D-D6981727D15B} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\t\t{84C08621-2C78-4B19-9454-7B9019E68326} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{1DD27CAF-AC19-4674-A42B-F15260929BAF} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{80A3B3BD-8D2F-471A-A198-576772FAA048} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{AEAEE225-1080-4CC9-8BA8-9F7580ED1B9B} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{98B0AE89-5D42-4366-9C0E-9392737E36AC} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{DF95A9DC-F6BE-4C71-B444-4092B43EB602} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\t\t{3E982150-5B43-44DA-8D96-66CF07A9A14C} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\t\t{1C890E49-5A9B-4EAB-9F69-6A6E78D82610} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\t\t{894B7986-5AA4-42A7-8EB0-6DFD1F604505} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\t\t{9C0602C2-00DD-43F4-B274-6598AF33C00A} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{C25452E1-AFF2-4579-B6B4-F040CAD02FDA} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{E66F281C-BD50-45B0-AAEF-FB87E4C9D0CC} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{2FE963BD-D826-4CC5-8A63-864CDA212233} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{7145E485-34FA-4632-89B0-BD27C96AF69C} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\t\t{68CD41F8-A6C3-4D43-93CA-92E898254CBD} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{BB84CC4C-EB11-4A61-8ED4-791EADAA46E1} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{706E37D7-B148-4734-9695-0D1AE6D4B3D5} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{257044FB-F7A8-499D-8EF2-B5CAD76D617A} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{99F3A36C-7930-4670-A8B3-7137D891671D} = {2A52BDC8-4B16-43FE-9E9D-A7D0A72C17C8}\n\t\t{CDFBE3EE-AFD7-467F-BE9C-F9EAFC7A05CE} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\t\t{D4624B9B-67A1-46D5-9468-58995B2720F9} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\t\t{C7C03D37-F2D2-4115-8423-86C1BF1B8A18} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\t\t{C9A993F7-E3E2-4FDC-AA1E-01348B023D16} = {5925E681-1BEA-456D-B9E0-CA175ABBFA9D}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tEnterpriseLibraryConfigurationToolBinariesPathV6 = packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\n\t\tSolutionGuid = {7A9645D4-78F9-451C-B788-6EC41CA3BF59}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Etg.Yams.sln.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue\">&lt;Policy Inspect=\"True\" Prefix=\"_\" Suffix=\"\" Style=\"aaBb\" /&gt;</s:String></wpf:ResourceDictionary>"
  },
  {
    "path": "LICENSE",
    "content": "YAMS\n\nCopyright (c) Microsoft Corporation\n\nAll rights reserved. \n\nMIT License\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."
  },
  {
    "path": "README.md",
    "content": "YAMS\n=======\n\n[![Join the chat at https://gitter.im/Microsoft/Yams](https://badges.gitter.im/Microsoft/Yams.svg)](https://gitter.im/Microsoft/Yams?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n[![Build status](https://ci.appveyor.com/api/projects/status/735m5td6npl08q8s/branch/master?svg=true)](https://ci.appveyor.com/project/NehmeBilal/yams/branch/master)\n\n**YAMS** (Yet Another Microservices Solution) is a library that can be used to deploy and host microservices on premises, in Azure, or on other cloud service platforms. It offers the following features:\n* **Quick deployments** of microservices to any target environment (~1 minute deployments to Azure). \n* **Sharing infrastructure** (multiple microservices can be deployed to the same on premises or cloud service). \n* **Scaling microservices independently**.\n* **Versioning** of microservices, quick **updates**, **reverts**, etc. \n* Support for **Upgrade Domains** to minimize (and potentially eliminate) application downtime during updates, including first-class support for **Azure Upgrade Domains**.\n* Microservices can be developed in **any programming language** and deployed with YAMS (as long as your service can be started with an exe).\n* **Health monitoring** and **graceful shutdown** of microservices.\n\nYAMS has first-class support for deploying applications from Azure **blob storage**, but with its pluggable storage architecture, other providers such as SQL Server or file storage can be created and plugged in as well.\n\nTo deploy an application to a YAMS cluster, simply drop the binaries of the application into YAMS deployment storage. The binaries are then picked-up by YAMS, deployed to all VMs in the cluster, and then launched.\n\nPlease read the documentation below for more information.\n\nDocumentation \n=======\n* [Yams Overview](Docs/Overview.md).\n* [Deploy YAMS to your cloud service](Docs/Deploy_YAMS.md).\n* [Deploy and host applications in YAMS](Docs/Deploy&Host_an_App_in_YAMS.md).\n* [Continuous Integration with YAMS and VSTS](Docs/Continuous_Integration.md).\n* [Deploy and host Orleans applications in YAMS](Docs/Deploy_Orleans_App_in_YAMS.md).\n* [Yams Storage Api](Docs/YAMS_Storage.md).\n* [Contributor Guide](Docs/Contributor_Guide.md).\n\nNuGets\n=======\n\n| Module  | NuGet |\n| ------------- | ------------- |\n| Etg.Yams  | [![NuGet](https://img.shields.io/nuget/v/Etg.Yams.svg?style=flat)](https://www.nuget.org/packages/Etg.Yams/)  |\n| Etg.Yams.Client  | [![NuGet](https://img.shields.io/nuget/v/Etg.Yams.Client.svg?style=flat)](https://www.nuget.org/packages/Etg.Yams.Client/)  |\n| Etg.Yams.Powershell  | [![NuGet](https://img.shields.io/nuget/v/Etg.Yams.Powershell.svg?style=flat)](https://www.nuget.org/packages/Etg.Yams.Powershell/)  |\n\nVideos\n=======\n* [Nehme Bilal and Reuben Bond talk about deploying Orleans with YAMS and Service Fabric](https://www.youtube.com/watch?v=w__D7gnqeZ0&feature=youtu.be).\n* [Jakub Konecki talk about deploying Orleans with YAMS](https://github.com/OrleansContrib/meetups#meetup-12-deploying-orleans-with-jakub-konecki).\n\nContribute!\n=======\nWe welcome contributions of all sorts including pull requests, suggestions, documentation, etc. Please feel free to open an issue to discuss any matter.\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\n\nLicense\n=======\nThis project is licensed under the [MIT license](LICENSE).\n"
  },
  {
    "path": "SECURITY.md",
    "content": "<!-- BEGIN MICROSOFT SECURITY.MD V0.0.8 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 [our GitHub organizations](https://opensource.microsoft.com/).\n\nIf you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), 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://aka.ms/opensource/security/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 [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).\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://aka.ms/opensource/security/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://aka.ms/opensource/security/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://aka.ms/opensource/security/cvd).\n\n<!-- END MICROSOFT SECURITY.MD BLOCK -->\n"
  },
  {
    "path": "Samples/Etg.Yams.ARM/Etg.Yams.ARM.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.24720.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams.Host\", \"Etg.Yams.Host\\Etg.Yams.Host.csproj\", \"{F8117C86-B429-4202-88E0-6BC98209DA51}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{1326E507-4598-48F7-B614-E264AEC34FD4}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tREADME.md = README.md\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{F8117C86-B429-4202-88E0-6BC98209DA51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F8117C86-B429-4202-88E0-6BC98209DA51}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F8117C86-B429-4202-88E0-6BC98209DA51}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F8117C86-B429-4202-88E0-6BC98209DA51}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tEnterpriseLibraryConfigurationToolBinariesPathV6 = packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Samples/Etg.Yams.ARM/Etg.Yams.Host/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.6.1\" />\n    </startup>\n  <appSettings>\n    <add key=\"UpdateFrequencyInSeconds\" value=\"5\" />\n    <add key=\"ApplicationRestartCount\" value=\"2\" />\n    <add key=\"LocalStoreDirectory\" value=\".\\LocalStore\" />\n    <add key=\"StorageDataConnectionString\" value=\"DefaultEndpointsProtocol=https;AccountName=piswitchlocal;AccountKey=5PaMlu8cLyFOlA8aR+n0VF0eOWZyDuO+uDcfdDgGm/DYTPQ4ohzBuUwRSiQ1xIcP01i4flNQFKZSLcfs68vo6Q==\" />\n  </appSettings>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.WindowsAzure.Storage\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-8.5.0.0\" newVersion=\"8.5.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Newtonsoft.Json\" publicKeyToken=\"30ad4fe6b2a6aeed\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-10.0.0.0\" newVersion=\"10.0.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.Data.Services.Client\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-5.8.3.0\" newVersion=\"5.8.3.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.Data.OData\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-5.8.3.0\" newVersion=\"5.8.3.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.Data.Edm\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-5.8.3.0\" newVersion=\"5.8.3.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.Azure.KeyVault.Core\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-2.0.0.0\" newVersion=\"2.0.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Autofac\" publicKeyToken=\"17863af14b0044da\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.6.2.0\" newVersion=\"4.6.2.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Reactive.Core\" publicKeyToken=\"94bc3704cddfc263\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-3.0.3000.0\" newVersion=\"3.0.3000.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Reactive.Linq\" publicKeyToken=\"94bc3704cddfc263\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-3.0.3000.0\" newVersion=\"3.0.3000.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>\n"
  },
  {
    "path": "Samples/Etg.Yams.ARM/Etg.Yams.Host/Etg.Yams.Host.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{F8117C86-B429-4202-88E0-6BC98209DA51}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Host</RootNamespace>\n    <AssemblyName>Etg.Yams.Host</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=4.6.2.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Autofac.4.6.2\\lib\\net45\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\CommandLineParser.1.9.71\\lib\\net45\\CommandLine.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.5.0\\lib\\net451\\Etg.Yams.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Etg.Yams.AzureBlobStorageDeploymentRepository, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.5.0\\lib\\net451\\Etg.Yams.AzureBlobStorageDeploymentRepository.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Etg.Yams.AzureBlobStorageUpdateSession, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.5.0\\lib\\net451\\Etg.Yams.AzureBlobStorageUpdateSession.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Etg.Yams.AzureUtils, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.5.0\\lib\\net451\\Etg.Yams.AzureUtils.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Etg.Yams.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.5.0\\lib\\net451\\Etg.Yams.Common.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Etg.Yams.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.5.0\\lib\\net451\\Etg.Yams.Core.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Azure.KeyVault.Core.2.0.4\\lib\\net45\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Edm.5.8.3\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.OData.5.8.3\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Services.Client.5.8.3\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Configuration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.WindowsAzure.ConfigurationManager.3.2.3\\lib\\net40\\Microsoft.WindowsAzure.Configuration.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\WindowsAzure.Storage.8.5.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.10.0.3\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.ComponentModel.Composition\" />\n    <Reference Include=\"System.configuration\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Drawing\" />\n    <Reference Include=\"System.IO.Compression.FileSystem\" />\n    <Reference Include=\"System.Numerics\" />\n    <Reference Include=\"System.Reactive.Core, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Reactive.Core.3.1.1\\lib\\net46\\System.Reactive.Core.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Reactive.Interfaces, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Reactive.Interfaces.3.1.1\\lib\\net45\\System.Reactive.Interfaces.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Reactive.Linq, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Reactive.Linq.3.1.1\\lib\\net46\\System.Reactive.Linq.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Reactive.PlatformServices, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Reactive.PlatformServices.3.1.1\\lib\\net46\\System.Reactive.PlatformServices.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Reactive.Windows.Threading.3.1.1\\lib\\net45\\System.Reactive.Windows.Threading.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Runtime.Serialization\" />\n    <Reference Include=\"System.Spatial, Version=5.8.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Spatial.5.8.3\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Windows\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n    <Reference Include=\"Topshelf, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Topshelf.4.0.3\\lib\\net452\\Topshelf.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Unity.Abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Unity.5.0.0\\lib\\net45\\Unity.Abstractions.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Unity.Container, Version=5.0.0.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Unity.5.0.0\\lib\\net45\\Unity.Container.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"WindowsBase\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\">\n      <SubType>Designer</SubType>\n    </None>\n    <None Include=\"packages.config\">\n      <SubType>Designer</SubType>\n    </None>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "Samples/Etg.Yams.ARM/Etg.Yams.Host/Program.cs",
    "content": "﻿#region\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net;\nusing System.Security.Permissions;\nusing System.Text;\nusing Microsoft.Win32;\nusing Topshelf;\nusing Topshelf.HostConfigurators;\n\n#endregion\n\nnamespace Etg.Yams.Host\n{\n    class Program\n    {\n        private static string _clusterId;\n        private static string _updateDomain;\n        private static string _deploymentRepositoryStorageConnectionString;\n        private static string _updateSessionStorageConnectionString;\n\n        private static IDictionary<string, string> _clusterProperties;\n        private static int? _updateFrequencyInSeconds;\n        private static int? _applicationRestartCount;\n\n        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]\n        static void Main(string[] args)\n        {\n            ServicePointManager.DefaultConnectionLimit = 1000;\n\n            HostFactory.Run(x =>\n            {\n                x.AddCommandLineDefinition(\"clusterId\", cid => _clusterId = cid);\n                x.AddCommandLineDefinition(\"updateDomain\", upd => _updateDomain = upd);\n                x.AddCommandLineDefinition(\"deploymentRepositoryStorageConnectionString\", drscs => _deploymentRepositoryStorageConnectionString = drscs);\n                x.AddCommandLineDefinition(\"updateSessionStorageConnectionString\", upscs => _updateSessionStorageConnectionString = upscs);\n                x.AddCommandLineDefinition(\"updateFrequency\", uf => _updateFrequencyInSeconds = Convert.ToInt32(uf));\n                x.AddCommandLineDefinition(\"applicationRestartCount\", arc => _applicationRestartCount = Convert.ToInt32(arc));\n                x.AddCommandLineDefinition(\"clusterProperties\", cp => _clusterProperties = cp.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(item => item.Split('=')).ToDictionary(s => s[0], s => s[1]));\n\n                x.ApplyCommandLine();\n\n                x.Service<IYamsService>(s =>\n                {\n                    s.ConstructUsing(name =>\n                    {\n                        if (string.IsNullOrWhiteSpace(_updateSessionStorageConnectionString))\n                            throw new ArgumentNullException(nameof(_updateSessionStorageConnectionString));\n\n                        if (string.IsNullOrWhiteSpace(_deploymentRepositoryStorageConnectionString))\n                            throw new ArgumentNullException(nameof(_deploymentRepositoryStorageConnectionString));\n\n                        if (string.IsNullOrWhiteSpace(_clusterId))\n                            throw new ArgumentNullException(nameof(_clusterId));\n\n                        if (string.IsNullOrWhiteSpace(_updateDomain))\n                            throw new ArgumentNullException(nameof(_updateDomain));\n\n                        // mandatory configs\n                        YamsConfigBuilder yamsConfigBuilder = new YamsConfigBuilder(\n                            _clusterId,\n                            _updateDomain,\n                            Environment.MachineName,\n                            Environment.CurrentDirectory + \"\\\\LocalStore\");\n\n                        // optional configs;\n                        if (_updateFrequencyInSeconds.HasValue)\n                            yamsConfigBuilder.SetCheckForUpdatesPeriodInSeconds(_updateFrequencyInSeconds.Value);\n\n                        if (_applicationRestartCount.HasValue)\n                            yamsConfigBuilder.SetApplicationRestartCount(_applicationRestartCount.Value);\n\n                        if (_clusterProperties!=null)\n                            yamsConfigBuilder.AddClusterProperties(_clusterProperties);\n\n                        var yamsConfig = yamsConfigBuilder.Build();\n\n                        return YamsServiceFactory.Create(yamsConfig,\n                            deploymentRepositoryStorageConnectionString: _deploymentRepositoryStorageConnectionString,\n                            updateSessionStorageConnectionString: _updateSessionStorageConnectionString);\n                    });\n                    s.WhenStarted(yep => yep.Start().Wait());\n                    s.WhenStopped(yep => yep.Stop().Wait());\n                });\n                x.RunAsLocalSystem();\n                x.AddCommandLineArgumentsToStartupParameters();\n\n                x.SetDescription(\"Yams Service Host\");\n                x.SetDisplayName($\"Yams Service [{_clusterId} - {_updateDomain}]\");\n                x.SetServiceName(\"Yams\");\n\n                x.EnableServiceRecovery(configurator =>\n                {\n                    configurator.OnCrashOnly();\n                    configurator.RestartService(0);\n                });\n                x.StartAutomatically();\n            });\n        }\n    }\n\n    public static class YamsConfigBuilderExtensions\n    {\n        public static YamsConfigBuilder AddClusterProperties(this YamsConfigBuilder yamsConfigBuilder,\n            IDictionary<string, string> properties)\n        {\n            foreach (var property in properties)\n            {\n                yamsConfigBuilder.AddClusterProperty(property.Key, property.Value);\n            }\n\n            return yamsConfigBuilder;\n        }\n    }\n\n    public static class HostConfigurationExtensions\n    {\n        private static readonly string[] TopShelfArguments =\n            {\"install\", \"-instance\", \"-displayname\", \"-servicename\", \"-description\", \"--\"};\n\n        public static void AddCommandLineArgumentsToStartupParameters(this HostConfigurator hostConfigurator)\n        {\n            hostConfigurator.AfterInstall(settings =>\n            {\n                using (RegistryKey system = Registry.LocalMachine.OpenSubKey(\"System\"))\n                using (RegistryKey currentControlSet = system.OpenSubKey(\"CurrentControlSet\"))\n                using (RegistryKey services = currentControlSet.OpenSubKey(\"Services\"))\n                using (RegistryKey service = services.OpenSubKey(settings.ServiceName, true))\n                {\n                    var arguments = Environment.GetCommandLineArgs();\n                    var imagePath = service.GetValue(\"ImagePath\");\n\n                    var newImagePath = arguments\n                        .Skip(1)\n                        .Where(a => !IsTopShelfArgument(a))\n                        .Aggregate(imagePath, (o1, o2) => $\"{o1} {o2}\");\n\n                    service.SetValue(\"ImagePath\", newImagePath, RegistryValueKind.String);\n                }\n            });\n        }\n\n        private static bool IsTopShelfArgument(string argument)\n        {\n            return TopShelfArguments.Any(w => argument.StartsWith(w, StringComparison.InvariantCultureIgnoreCase));\n        }\n    }\n}"
  },
  {
    "path": "Samples/Etg.Yams.ARM/Etg.Yams.Host/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Etg.Yams.Host\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Etg.Yams.Host\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"f8117c86-b429-4202-88e0-6bc98209da51\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/Etg.Yams.ARM/Etg.Yams.Host/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"4.6.2\" targetFramework=\"net461\" />\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"net461\" />\n  <package id=\"EnterpriseLibrary.TransientFaultHandling\" version=\"6.0.1304.0\" targetFramework=\"net461\" />\n  <package id=\"Etg.Yams\" version=\"1.5.0\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"2.0.4\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.3\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.3\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.3\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.WindowsAzure.ConfigurationManager\" version=\"3.2.3\" targetFramework=\"net461\" />\n  <package id=\"Newtonsoft.Json\" version=\"10.0.3\" targetFramework=\"net461\" />\n  <package id=\"Rx-Core\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"Rx-Interfaces\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"Rx-Linq\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"Rx-Main\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"Rx-PlatformServices\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net461\" />\n  <package id=\"System.Reactive\" version=\"3.1.1\" targetFramework=\"net461\" />\n  <package id=\"System.Reactive.Core\" version=\"3.1.1\" targetFramework=\"net461\" />\n  <package id=\"System.Reactive.Interfaces\" version=\"3.1.1\" targetFramework=\"net461\" />\n  <package id=\"System.Reactive.Linq\" version=\"3.1.1\" targetFramework=\"net461\" />\n  <package id=\"System.Reactive.PlatformServices\" version=\"3.1.1\" targetFramework=\"net461\" />\n  <package id=\"System.Reactive.Windows.Threading\" version=\"3.1.1\" targetFramework=\"net461\" />\n  <package id=\"System.Runtime\" version=\"4.3.0\" targetFramework=\"net461\" />\n  <package id=\"System.Spatial\" version=\"5.8.3\" targetFramework=\"net461\" />\n  <package id=\"Topshelf\" version=\"4.0.3\" targetFramework=\"net461\" />\n  <package id=\"Unity\" version=\"5.0.0\" targetFramework=\"net461\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.5.0\" targetFramework=\"net461\" />\n</packages>"
  },
  {
    "path": "Samples/Etg.Yams.ARM/README.md",
    "content": "# Yams Console/Windows Service Host #\n\nThe idea with this sample project is to be used as a Yams cluster note on a regular Virtual Machine.\n\n## How to run? ##\n\nIn order to run it as a console app, call the following command line:\n\n```\nEtg.Yams.Host.exe -deploymentId:MyDeploymentId -updateDomain:MyUpdateDomain -storageAccount:__MYSTORAGEACC__ -storageKey:__MYSTORAGEKEY__ -updateFrequency:5 -applicationRestartCount:2\n```\n\nIf you want to install it as a Windows Service add the `-install` parameter to the command-line.\n\nReplace the parameters as follow:\n\n- deploymentId: The Yams Cluster Deployment Id\n- updateDomain: The update domain\n- storageAccount: Azure Storage account name\n- storageKey: Azure Storage account key\n- updateFrequency: regular Yams update frequency (in second)\n- applicationRestartCount: regular Yams parameter\n\nThose parameters can be set on the project property for debug purposes.\n\n## What is next? ##\n\n1. Create a Chocolatey package and publish it to chocolatey.org\n2. Create an Azure Resource Manager (ARM) Template\n3. Put a on-click-deply link on Yams repo so people will be able to deploy a Yams cluster by just click on this link and fill the wizard parameters.\n\n\nMore news soon!\n\n[]s "
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Backend/Backend.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProductVersion>8.0.30703</ProductVersion>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Backend</RootNamespace>\n    <AssemblyName>Backend</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <RoleType>Worker</RoleType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Edm.5.6.4\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.OData.5.6.4\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Services.Client.5.6.4\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Diagnostics, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\">\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.ServiceRuntime, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\">\n      <Private>False</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\WindowsAzure.Storage.7.0.0\\lib\\net40\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Spatial.5.6.4\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"WorkerRole.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\">\n      <SubType>Designer</SubType>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Etg.Yams.WorkerRole\\Etg.Yams.WorkerRole.csproj\">\n      <Project>{b38d7d2a-bdc1-49fe-b0dd-d799e3e746ad}</Project>\n      <Name>Etg.Yams.WorkerRole</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n  <PropertyGroup>\n    <!-- Setting AutoUnifyAssemblyReferences to false will allow the ResolveAssemblyReferences task to \n    create warnings when detecting version missmatches among references.\n    -->\n    <AutoUnifyAssemblyReferences>false</AutoUnifyAssemblyReferences>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Backend/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Backend\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Backend\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"d6eb9dd4-4dc6-4cf1-888b-4a4a548e3fd1\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Backend/WorkerRole.cs",
    "content": "using Etg.Yams.WorkerRole;\n\nnamespace Backend\n{\n    public class WorkerRole : YamsWorkerRole\n    {\n        protected override bool IsSingleClusterDeployment\n        {\n            get { return false; }\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Backend/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <system.diagnostics>\n    <trace>\n      <listeners>\n        <add type=\"Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\" name=\"AzureDiagnostics\">\n          <filter type=\"\" />\n        </add>\n      </listeners>\n    </trace>\n  </system.diagnostics>  \n  <runtime>\n    <gcServer enabled=\"true\"></gcServer>\n    <gcConcurrent enabled=\"false\"></gcConcurrent>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"MonAgentListener\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-1.0.0.0\" newVersion=\"1.0.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.WindowsAzure.Storage\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-7.0.0.0\" newVersion=\"7.0.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" /></startup></configuration>\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Backend/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"7.0.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.MultipleClusters/BackendContent/GCSettingsManagement.ps1",
    "content": "﻿<#\n//*********************************************************\n//\n//    Copyright (c) Microsoft. All rights reserved.\n//    This code is licensed under the Microsoft Public License.\n//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF\n//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY\n//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR\n//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.\n//\n//*********************************************************\n#>\nParam\n(\n\t$serverGC = $True,\n\t$backgroundGC = $True\n)\n\n[string]$configFilePath = \"$(${env:RoleRoot})\\base\\x64\\WaWorkerHost.exe.config\"\n\nfunction Create-ConfigFileIfNotExists\n{\n\t# Only create the Xml document if it does not already exist\n\tif(-not (Test-Path -Path $configFilePath -PathType Leaf))\n\t{\n\t\t[System.Xml.XmlDocument]$document = New-Object System.Xml.XmlDocument\n\t\t\n\t\t# config file doesn't exist create a now one\n \t\t[System.Xml.XmlDeclaration]$prolog = $document.CreateXmlDeclaration(\"1.0\", \"utf-8\", $null)\n \t\t[System.Xml.XmlNode]$child = $document.AppendChild($prolog)\n\t\t[System.Xml.XmlElement]$configurationElement = Append-ElementIfNotExists $document $document.DocumentElement \"configuration\"\n\t\t\n\t\t# Save a copy of the document\n\t\t$document.Save($configFilePath)\n\t}\n}\n\nfunction Load-ConfigFile\n{\n\t[System.Xml.XmlDocument]$document = New-Object System.Xml.XmlDocument\n\t\n\t#Check if the document already exists and load it if it does not\n\tif(Test-Path -Path $configFilePath -PathType Leaf)\n\t{\n\t\t$document.Load($configFilePath)\n\t}\n\t\n\treturn $document\n}\n\nfunction Append-ElementIfNotExists\n{\n\tparam\n\t(\n\t\t[System.Xml.XmlDocument]$document,\n\t\t[System.Xml.XmlElement]$parent,\n\t\t[string]$elementName\n\t)\n\t[System.Xml.XmlElement]$element = $null\n\t[System.Xml.XmlNode]$parentNode = $parent\n\t\n\tif($document -ne $null)\n\t{\n\t\tif($parentNode -eq $null)\n\t\t{\n\t\t\t$parentNode = $document\n\t\t}\n\t\t\n\t\t$element = $parentNode.SelectSingleNode(\"./$($elementName)\")\n\t\t\n\t\tif($element -eq $null)\n\t\t{\n\t\t\t$element = $document.CreateElement($elementName)\n\t\t\t[System.Xml.XmlElement]$child = $parentNode.AppendChild($element)\n\t\t}\n\t}\n\t\n\treturn $element\n}\n\nfunction Create-ElementStructureIfNotExists\n{\n\tparam\n\t(\n\t\t[System.Xml.XmlDocument]$document\n\t)\n\t[bool]$isSuccess = $false\n\t\n\tif($document -ne $null)\n\t{\n\t\t[System.Xml.XmlElement]$configurationElement = Append-ElementIfNotExists $document $null \"configuration\"\n\t\t\n\t\tif($configurationElement -ne $null)\n\t\t{\n\t\t\t[System.Xml.XmlElement]$element = Append-ElementIfNotExists $document $configurationElement \"runtime\"\n\t\t\t\n\t\t\t$isSuccess = $element -ne $null\n\t\t}\n\t}\n\t\n\treturn $isSuccess\n}\n\n# Create the document if required\nCreate-ConfigFileIfNotExists\n\n# Load the configuration file into the XML document\n[System.Xml.XmlDocument]$configurationDocument = Load-ConfigFile\n\t\nif($configurationDocument -ne $null)\n{\n\tif(Create-ElementStructureIfNotExists $configurationDocument)\n\t{\n\t\t# All of the entries are on the runtime element\n\t\t[System.Xml.XmlElement]$runtimeElement = $configurationDocument.DocumentElement.SelectSingleNode('./runtime')\n\t\t\n\t\tif($runtimeElement -ne $null)\n\t\t{\n\t\t\t# Set the Server GC to enabled if requested\n\t\t\t[System.Xml.XmlElement]$serverGCElement = Append-ElementIfNotExists $configurationDocument $runtimeElement \"gcServer\"\n\t\t\t$serverGCElement.SetAttribute(\"enabled\", $serverGC.ToString([System.Globalization.CultureInfo]::InvariantCulture).ToLower()) \n\n\t\t\t# Set the concurrent GC to enabled if requested\n\t\t\t[System.Xml.XmlElement]$concurrentGCElement = Append-ElementIfNotExists $configurationDocument $runtimeElement \"gcConcurrent\"\n\t\t\t$concurrentGCElement.SetAttribute(\"enabled\", $backgroundGC.ToString([System.Globalization.CultureInfo]::InvariantCulture).ToLower()) \n\t\t}\n\t}\n\t\n\t# Save the document\n\t$configurationDocument.Save($configFilePath)\n}\n\n\n\n \n \n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.MultipleClusters/BackendContent/ServerGC.cmd",
    "content": "﻿REM Check if the script is running in the Azure Emulator, and if so, do not run\nREM IF \"%IsEmulated%\"==\"true\" goto :EOF \nIf \"%UseServerGC%\"==\"False\" GOTO :ValidateBackground\nIf \"%UseServerGC%\"==\"0\" GOTO :ValidateBackground\n\nSET UseServerGC=\"True\"\n\n:ValidateBackground\nIf \"%UseBackgroundGC%\"==\"False\" GOTO :CommandExecution\nIf \"%UseBackgroundGC%\"==\"0\" GOTO :CommandExecution\nSET UseBackgroundGC=\"True\"\n\n:CommandExecution\nPowerShell.exe -executionpolicy unrestricted -command \".\\GCSettingsManagement.ps1\" -serverGC %UseServerGC% -backgroundGC %UseBackgroundGC%\n\nExit /b"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.MultipleClusters/BackendContent/diagnostics.wadcfgx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<DiagnosticsConfiguration  xmlns=\"http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration\">\n  <PublicConfig>\n    <WadCfg>\n      <DiagnosticMonitorConfiguration overallQuotaInMB=\"4096\">\n        <DiagnosticInfrastructureLogs scheduledTransferLogLevelFilter=\"Error\"/>\n        <Logs scheduledTransferPeriod=\"PT1M\" scheduledTransferLogLevelFilter=\"Information\" />\n        <Directories scheduledTransferPeriod=\"PT1M\">\n          <IISLogs containerName =\"wad-iis-logfiles\" />\n          <FailedRequestLogs containerName =\"wad-failedrequestlogs\" />\n        </Directories>\n        <WindowsEventLog scheduledTransferPeriod=\"PT1M\" >\n          <DataSource name=\"Application!*[System[(Level=1 or Level=2 or Level=3)]]\" />\n          <DataSource name=\"Windows Azure!*[System[(Level=1 or Level=2 or Level=3 or Level=4)]]\" />\n        </WindowsEventLog>\n        <CrashDumps containerName=\"wad-crashdumps\" dumpType=\"Mini\">\n          <CrashDumpConfiguration processName=\"WaIISHost.exe\"/>\n          <CrashDumpConfiguration processName=\"WaWorkerHost.exe\"/>\n          <CrashDumpConfiguration processName=\"w3wp.exe\"/>\n        </CrashDumps>\n        <PerformanceCounters scheduledTransferPeriod=\"PT1M\">\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\Available MBytes\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Web Service(_Total)\\ISAPI Extension Requests/sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Web Service(_Total)\\Bytes Total/Sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET Applications(__Total__)\\Requests/Sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET Applications(__Total__)\\Errors Total/Sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET\\Requests Queued\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET\\Requests Rejected\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Processor(_Total)\\% Processor Time\" sampleRate=\"PT3M\" />\n        </PerformanceCounters>\n      </DiagnosticMonitorConfiguration>\n    </WadCfg>\n    <StorageAccount></StorageAccount>\n  </PublicConfig>\n  <PrivateConfig>\n    <StorageAccount name=\"\" key=\"\" endpoint=\"\" />\n  </PrivateConfig>\n  <IsEnabled>true</IsEnabled>\n</DiagnosticsConfiguration>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.MultipleClusters/Etg.Yams.Cloud.MultipleClusters.ccproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProductVersion>2.9</ProductVersion>\n    <ProjectGuid>f9c2b6e8-6d14-4201-956a-a2e93073cbbc</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Cloud</RootNamespace>\n    <AssemblyName>Etg.Yams.Cloud</AssemblyName>\n    <StartDevelopmentStorage>True</StartDevelopmentStorage>\n    <Name>Etg.Yams.Cloud.MultipleClusters</Name>\n    <SccProjectName>SAK</SccProjectName>\n    <SccProvider>SAK</SccProvider>\n    <SccAuxPath>SAK</SccAuxPath>\n    <SccLocalPath>SAK</SccLocalPath>\n    <UseWebProjectPorts>True</UseWebProjectPorts>\n    <PackageEnableRemoteDebugger>True</PackageEnableRemoteDebugger>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <!-- Items for the project -->\n  <ItemGroup>\n    <ServiceDefinition Include=\"ServiceDefinition.csdef\" />\n    <ServiceConfiguration Include=\"ServiceConfiguration.Local.cscfg\" />\n    <ServiceConfiguration Include=\"ServiceConfiguration.Cloud.cscfg\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Folder Include=\"BackendContent\\\" />\n    <Folder Include=\"FrontendContent\\\" />\n    <Folder Include=\"Profiles\" />\n  </ItemGroup>\n  <ItemGroup>\n    <DiagnosticsConfiguration Include=\"BackendContent\\diagnostics.wadcfgx\" />\n    <DiagnosticsConfiguration Include=\"FrontendContent\\diagnostics.wadcfgx\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Backend\\Backend.csproj\">\n      <Name>Backend</Name>\n      <Project>{d6eb9dd4-4dc6-4cf1-888b-4a4a548e3fd1}</Project>\n      <Private>True</Private>\n      <RoleType>Worker</RoleType>\n      <RoleName>Backend</RoleName>\n      <UpdateDiagnosticsConnectionStringOnPublish>True</UpdateDiagnosticsConnectionStringOnPublish>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Frontend\\Frontend.csproj\">\n      <Name>Frontend</Name>\n      <Project>{c80821c2-215c-429e-a6a3-bfb132b5c1f4}</Project>\n      <Private>True</Private>\n      <RoleType>Worker</RoleType>\n      <RoleName>Frontend</RoleName>\n      <UpdateDiagnosticsConnectionStringOnPublish>True</UpdateDiagnosticsConnectionStringOnPublish>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"BackendContent\\GCSettingsManagement.ps1\">\n      <SubType>Content</SubType>\n    </Content>\n    <Content Include=\"BackendContent\\ServerGC.cmd\">\n      <SubType>Content</SubType>\n    </Content>\n  </ItemGroup>\n  <!-- Import the target files for this project template -->\n  <PropertyGroup>\n    <VisualStudioVersion Condition=\" '$(VisualStudioVersion)' == '' \">10.0</VisualStudioVersion>\n    <CloudExtensionsDir Condition=\" '$(CloudExtensionsDir)' == '' \">$(MSBuildExtensionsPath)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)\\Windows Azure Tools\\2.9\\</CloudExtensionsDir>\n  </PropertyGroup>\n  <Import Project=\"$(CloudExtensionsDir)Microsoft.WindowsAzure.targets\" />\n</Project>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.MultipleClusters/FrontendContent/diagnostics.wadcfgx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<DiagnosticsConfiguration  xmlns=\"http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration\">\n  <PublicConfig>\n    <WadCfg>\n      <DiagnosticMonitorConfiguration overallQuotaInMB=\"4096\">\n        <DiagnosticInfrastructureLogs scheduledTransferLogLevelFilter=\"Error\"/>\n        <Logs scheduledTransferPeriod=\"PT1M\" scheduledTransferLogLevelFilter=\"Information\" />\n        <Directories scheduledTransferPeriod=\"PT1M\">\n          <IISLogs containerName =\"wad-iis-logfiles\" />\n          <FailedRequestLogs containerName =\"wad-failedrequestlogs\" />\n        </Directories>\n        <WindowsEventLog scheduledTransferPeriod=\"PT1M\" >\n          <DataSource name=\"Application!*[System[(Level=1 or Level=2 or Level=3)]]\" />\n          <DataSource name=\"Windows Azure!*[System[(Level=1 or Level=2 or Level=3 or Level=4)]]\" />\n        </WindowsEventLog>\n        <CrashDumps containerName=\"wad-crashdumps\" dumpType=\"Mini\">\n          <CrashDumpConfiguration processName=\"WaIISHost.exe\"/>\n          <CrashDumpConfiguration processName=\"WaWorkerHost.exe\"/>\n          <CrashDumpConfiguration processName=\"w3wp.exe\"/>\n        </CrashDumps>\n        <PerformanceCounters scheduledTransferPeriod=\"PT1M\">\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\Available MBytes\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Web Service(_Total)\\ISAPI Extension Requests/sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Web Service(_Total)\\Bytes Total/Sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET Applications(__Total__)\\Requests/Sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET Applications(__Total__)\\Errors Total/Sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET\\Requests Queued\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET\\Requests Rejected\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Processor(_Total)\\% Processor Time\" sampleRate=\"PT3M\" />\n        </PerformanceCounters>\n      </DiagnosticMonitorConfiguration>\n    </WadCfg>\n    <StorageAccount></StorageAccount>\n  </PublicConfig>\n  <PrivateConfig>\n    <StorageAccount name=\"\" key=\"\" endpoint=\"\" />\n  </PrivateConfig>\n  <IsEnabled>true</IsEnabled>\n</DiagnosticsConfiguration>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.MultipleClusters/ServiceConfiguration.Cloud.cscfg",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ServiceConfiguration serviceName=\"Etg.Yams.Cloud\" xmlns=\"http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration\" osFamily=\"4\" osVersion=\"*\" schemaVersion=\"2015-04.2.6\">\n  <Role name=\"Frontend\">\n    <Instances count=\"3\" />\n    <ConfigurationSettings>\n      <Setting name=\"StorageDataConnectionString\" value=\"MY_DATA_CONNECTION_STRING_FOR_THE_BLOB_STORAGE\" />\n      <Setting name=\"UpdateFrequencyInSeconds\" value=\"10\" />\n      <Setting name=\"ApplicationRestartCount\" value=\"3\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString\" value=\"MY_DATA_CONNECTION_STRING_FOR_LOGS\"/>\n    </ConfigurationSettings>\n    <Certificates>\n      <!--Replace thumbprints with your own-->\n      <Certificate name=\"MY_CERTIFICATE\" thumbprintAlgorithm=\"sha1\" thumbprint=\"MY_THUMBPRINT\" />\n      <Certificate name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption\" thumbprint=\"MY_THUMBPRINT\" thumbprintAlgorithm=\"sha1\" />\n    </Certificates>\n  </Role>\n  <Role name=\"Backend\">\n    <Instances count=\"3\" />\n    <ConfigurationSettings>\n      <Setting name=\"StorageDataConnectionString\" value=\"MY_DATA_CONNECTION_STRING_FOR_THE_BLOB_STORAGE\" />\n      <Setting name=\"UpdateFrequencyInSeconds\" value=\"10\" />\n      <Setting name=\"ApplicationRestartCount\" value=\"3\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString\" value=\"MY_DATA_CONNECTION_STRING_FOR_LOGS\"/>\n    </ConfigurationSettings>\n    <Certificates>\n      <!--Replace thumbprints with your own-->\n      <Certificate name=\"MY_CERTIFICATE\" thumbprintAlgorithm=\"sha1\" thumbprint=\"MY_THUMBPRINT\" />\n      <Certificate name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption\" thumbprint=\"MY_THUMBPRINT\" thumbprintAlgorithm=\"sha1\" />\n    </Certificates>\n  </Role>\n</ServiceConfiguration>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.MultipleClusters/ServiceConfiguration.Local.cscfg",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ServiceConfiguration serviceName=\"Etg.Yams.Cloud\" xmlns=\"http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration\" osFamily=\"4\" osVersion=\"*\" schemaVersion=\"2015-04.2.6\">\n  <Role name=\"Frontend\">\n    <Instances count=\"1\" />\n    <ConfigurationSettings>\n      <Setting name=\"StorageDataConnectionString\" value=\"UseDevelopmentStorage=true\" />\n      <Setting name=\"UpdateFrequencyInSeconds\" value=\"5\" />\n      <Setting name=\"ApplicationRestartCount\" value=\"3\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString\" value=\"UseDevelopmentStorage=true\"/>\n    </ConfigurationSettings>\n    <Certificates>\n      <!--Replace thumbprints with your own-->\n      <Certificate name=\"MY_CERTIFICATE\" thumbprintAlgorithm=\"sha1\" thumbprint=\"MY_THUMBPRINT\" />\n      <Certificate name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption\" thumbprint=\"MY_THUMBPRINT\" thumbprintAlgorithm=\"sha1\" />\n    </Certificates>\n  </Role>\n  <Role name=\"Backend\">\n    <Instances count=\"1\" />\n    <ConfigurationSettings>\n      <Setting name=\"StorageDataConnectionString\" value=\"UseDevelopmentStorage=true\" />\n      <Setting name=\"UpdateFrequencyInSeconds\" value=\"5\" />\n      <Setting name=\"ApplicationRestartCount\" value=\"3\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString\" value=\"UseDevelopmentStorage=true\"/>\n    </ConfigurationSettings>\n    <Certificates>\n      <!--Replace thumbprints with your own-->\n      <Certificate name=\"MY_CERTIFICATE\" thumbprintAlgorithm=\"sha1\" thumbprint=\"MY_THUMBPRINT\" />\n      <Certificate name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption\" thumbprint=\"MY_THUMBPRINT\" thumbprintAlgorithm=\"sha1\" />\n    </Certificates>\n  </Role>\n</ServiceConfiguration>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.MultipleClusters/ServiceDefinition.csdef",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ServiceDefinition name=\"Etg.Yams.Cloud\" xmlns=\"http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition\" schemaVersion=\"2015-04.2.6\" upgradeDomainCount=\"5\">\n  <WorkerRole name=\"Frontend\" vmsize=\"ExtraLarge\">\n    <Runtime executionContext=\"elevated\" />\n    <Imports>\n      <Import moduleName=\"RemoteAccess\" />\n      <Import moduleName=\"RemoteForwarder\" />\n    </Imports>\n    <ConfigurationSettings>\n      <Setting name=\"StorageDataConnectionString\" />\n      <Setting name=\"UpdateFrequencyInSeconds\" />\n      <Setting name=\"ApplicationRestartCount\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString\"/>\n    </ConfigurationSettings>\n    <Endpoints>\n      <InputEndpoint name=\"HttpsIn\" protocol=\"https\" port=\"443\" certificate=\"MY_CERTIFICATE\" />\n      <InputEndpoint name=\"HttpIn\" protocol=\"http\" port=\"80\" />\n    </Endpoints>\n    <LocalResources>\n      <LocalStorage name=\"LocalStoreDirectory\" cleanOnRoleRecycle=\"false\" />\n    </LocalResources>\n    <Certificates>\n      <Certificate name=\"MY_CERTIFICATE\" storeLocation=\"LocalMachine\" storeName=\"MY_STORE_NAME\" />\n    </Certificates>\n  </WorkerRole>\n  <WorkerRole name=\"Backend\" vmsize=\"ExtraLarge\">\n    <Runtime executionContext=\"elevated\" />\n    <Imports>\n      <Import moduleName=\"RemoteAccess\" />\n      <Import moduleName=\"RemoteForwarder\" />\n    </Imports>\n    <ConfigurationSettings>\n      <Setting name=\"StorageDataConnectionString\" />\n      <Setting name=\"UpdateFrequencyInSeconds\" />\n      <Setting name=\"ApplicationRestartCount\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString\"/>\n    </ConfigurationSettings>\n    <Endpoints>\n      <InternalEndpoint name=\"TcpEndpoints\" protocol=\"tcp\">\n        <FixedPortRange min=\"81\" max=\"400\" />\n      </InternalEndpoint>\n    </Endpoints>\n    <LocalResources>\n      <LocalStorage name=\"LocalStoreDirectory\" cleanOnRoleRecycle=\"false\" />\n    </LocalResources>\n    <Certificates>\n      <Certificate name=\"MY_CERTIFICATE\" storeLocation=\"LocalMachine\" storeName=\"MY_STORE_NAME\" />\n    </Certificates>\n    <Startup>\n      <Task commandLine=\"ServerGC.cmd\" executionContext=\"elevated\" taskType=\"simple\">\n        <Environment>\n          <Variable name=\"UseServerGC\" value=\"True\" />\n          <Variable name=\"UseBackgroundGC\" value=\"True\" />\n        </Environment>\n      </Task>\n    </Startup>\n  </WorkerRole>\n</ServiceDefinition>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.MultipleClusters.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.25123.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams.WorkerRole\", \"Etg.Yams.WorkerRole\\Etg.Yams.WorkerRole.csproj\", \"{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Frontend\", \"Frontend\\Frontend.csproj\", \"{C80821C2-215C-429E-A6A3-BFB132B5C1F4}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Backend\", \"Backend\\Backend.csproj\", \"{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}\"\nEndProject\nProject(\"{CC5FD16D-436D-48AD-A40C-5A424C6E3E79}\") = \"Etg.Yams.Cloud.MultipleClusters\", \"Etg.Yams.Cloud.MultipleClusters\\Etg.Yams.Cloud.MultipleClusters.ccproj\", \"{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C80821C2-215C-429E-A6A3-BFB132B5C1F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C80821C2-215C-429E-A6A3-BFB132B5C1F4}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C80821C2-215C-429E-A6A3-BFB132B5C1F4}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C80821C2-215C-429E-A6A3-BFB132B5C1F4}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tEnterpriseLibraryConfigurationToolBinariesPathV6 = packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.SingleCluster/Etg.Yams.Cloud.SingleCluster.ccproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProductVersion>2.9</ProductVersion>\n    <ProjectGuid>f9c2b6e8-6d14-4201-956a-a2e93073cbbc</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Cloud</RootNamespace>\n    <AssemblyName>Etg.Yams.Cloud</AssemblyName>\n    <StartDevelopmentStorage>True</StartDevelopmentStorage>\n    <Name>Etg.Yams.Cloud.SingleCluster</Name>\n    <SccProjectName>SAK</SccProjectName>\n    <SccProvider>SAK</SccProvider>\n    <SccAuxPath>SAK</SccAuxPath>\n    <SccLocalPath>SAK</SccLocalPath>\n    <UseWebProjectPorts>True</UseWebProjectPorts>\n    <PackageEnableRemoteDebugger>True</PackageEnableRemoteDebugger>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <!-- Items for the project -->\n  <ItemGroup>\n    <ServiceDefinition Include=\"ServiceDefinition.csdef\" />\n    <ServiceConfiguration Include=\"ServiceConfiguration.Local.cscfg\" />\n    <ServiceConfiguration Include=\"ServiceConfiguration.Cloud.cscfg\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Folder Include=\"Profiles\" />\n    <Folder Include=\"SingleClusterRoleContent\\\" />\n  </ItemGroup>\n  <ItemGroup>\n    <DiagnosticsConfiguration Include=\"SingleClusterRoleContent\\diagnostics.wadcfgx\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\SingleClusterRole\\SingleClusterRole.csproj\">\n      <Name>SingleClusterRole</Name>\n      <Project>{d6eb9dd4-4dc6-4cf1-888b-4a4a548e3fd1}</Project>\n      <Private>True</Private>\n      <RoleType>Worker</RoleType>\n      <RoleName>SingleClusterRole</RoleName>\n      <UpdateDiagnosticsConnectionStringOnPublish>True</UpdateDiagnosticsConnectionStringOnPublish>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"SingleClusterRoleContent\\GCSettingsManagement.ps1\">\n      <SubType>Content</SubType>\n    </Content>\n    <Content Include=\"SingleClusterRoleContent\\ServerGC.cmd\">\n      <SubType>Content</SubType>\n    </Content>\n  </ItemGroup>\n  <!-- Import the target files for this project template -->\n  <PropertyGroup>\n    <VisualStudioVersion Condition=\" '$(VisualStudioVersion)' == '' \">10.0</VisualStudioVersion>\n    <CloudExtensionsDir Condition=\" '$(CloudExtensionsDir)' == '' \">$(MSBuildExtensionsPath)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)\\Windows Azure Tools\\2.9\\</CloudExtensionsDir>\n  </PropertyGroup>\n  <Import Project=\"$(CloudExtensionsDir)Microsoft.WindowsAzure.targets\" />\n</Project>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.SingleCluster/ServiceConfiguration.Cloud.cscfg",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ServiceConfiguration serviceName=\"Etg.Yams.Cloud\" xmlns=\"http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration\" osFamily=\"4\" osVersion=\"*\" schemaVersion=\"2015-04.2.6\">\n  <Role name=\"SingleClusterRole\">\n    <Instances count=\"3\" />\n    <ConfigurationSettings>\n      <Setting name=\"StorageDataConnectionString\" value=\"MY_DATA_CONNECTION_STRING_FOR_THE_BLOB_STORAGE\" />\n      <Setting name=\"UpdateFrequencyInSeconds\" value=\"10\" />\n      <Setting name=\"ApplicationRestartCount\" value=\"3\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString\" value=\"MY_DATA_CONNECTION_STRING_FOR_LOGS\" />\n    </ConfigurationSettings>\n    <Certificates>\n      <!--Replace thumbprints with your own-->\n      <Certificate name=\"MY_CERTIFICATE\" thumbprintAlgorithm=\"sha1\" thumbprint=\"MY_THUMBPRINT\" />\n      <Certificate name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption\" thumbprint=\"MY_THUMBPRINT\" thumbprintAlgorithm=\"sha1\" />\n    </Certificates>\n  </Role>\n</ServiceConfiguration>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.SingleCluster/ServiceConfiguration.Local.cscfg",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ServiceConfiguration serviceName=\"Etg.Yams.Cloud\" xmlns=\"http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration\" osFamily=\"4\" osVersion=\"*\" schemaVersion=\"2015-04.2.6\">\n  <Role name=\"SingleClusterRole\">\n    <Instances count=\"1\" />\n    <ConfigurationSettings>\n      <Setting name=\"StorageDataConnectionString\" value=\"UseDevelopmentStorage=true\" />\n      <Setting name=\"UpdateFrequencyInSeconds\" value=\"5\" />\n      <Setting name=\"ApplicationRestartCount\" value=\"3\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled\" value=\"\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString\" value=\"UseDevelopmentStorage=true\" />\n    </ConfigurationSettings>\n    <Certificates>\n      <!--Replace thumbprints with your own-->\n      <Certificate name=\"MY_CERTIFICATE\" thumbprintAlgorithm=\"sha1\" thumbprint=\"MY_THUMBPRINT\" />\n      <Certificate name=\"Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption\" thumbprint=\"MY_THUMBPRINT\" thumbprintAlgorithm=\"sha1\" />\n    </Certificates>\n  </Role>\n</ServiceConfiguration>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.SingleCluster/ServiceDefinition.csdef",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ServiceDefinition name=\"Etg.Yams.Cloud\" xmlns=\"http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition\" schemaVersion=\"2015-04.2.6\" upgradeDomainCount=\"5\">\n  <WorkerRole name=\"SingleClusterRole\" vmsize=\"ExtraLarge\">\n    <Runtime executionContext=\"elevated\" />\n    <Imports>\n      <Import moduleName=\"RemoteAccess\" />\n      <Import moduleName=\"RemoteForwarder\" />\n    </Imports>\n    <ConfigurationSettings>\n      <Setting name=\"StorageDataConnectionString\" />\n      <Setting name=\"UpdateFrequencyInSeconds\" />\n      <Setting name=\"ApplicationRestartCount\" />\n      <Setting name=\"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString\"/>\n    </ConfigurationSettings>\n    <Endpoints>\n      <InputEndpoint name=\"HttpsIn\" protocol=\"https\" port=\"443\" certificate=\"MY_CERTIFICATE\" />\n      <InputEndpoint name=\"HttpIn\" protocol=\"http\" port=\"80\" />\n      <InternalEndpoint name=\"TcpEndpoints\" protocol=\"tcp\">\n        <FixedPortRange min=\"81\" max=\"400\" />\n      </InternalEndpoint>\n    </Endpoints>\n    <LocalResources>\n      <LocalStorage name=\"LocalStoreDirectory\" cleanOnRoleRecycle=\"false\" />\n    </LocalResources>\n    <Certificates>\n      <Certificate name=\"MY_CERTIFICATE\" storeLocation=\"LocalMachine\" storeName=\"MY_STORE_NAME\" />\n    </Certificates>\n    <Startup>\n      <Task commandLine=\"ServerGC.cmd\" executionContext=\"elevated\" taskType=\"simple\">\n        <Environment>\n          <Variable name=\"UseServerGC\" value=\"True\" />\n          <Variable name=\"UseBackgroundGC\" value=\"True\" />\n        </Environment>\n      </Task>\n    </Startup>\n  </WorkerRole>\n</ServiceDefinition>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.SingleCluster/SingleClusterRoleContent/GCSettingsManagement.ps1",
    "content": "﻿<#\n//*********************************************************\n//\n//    Copyright (c) Microsoft. All rights reserved.\n//    This code is licensed under the Microsoft Public License.\n//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF\n//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY\n//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR\n//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.\n//\n//*********************************************************\n#>\nParam\n(\n\t$serverGC = $True,\n\t$backgroundGC = $True\n)\n\n[string]$configFilePath = \"$(${env:RoleRoot})\\base\\x64\\WaWorkerHost.exe.config\"\n\nfunction Create-ConfigFileIfNotExists\n{\n\t# Only create the Xml document if it does not already exist\n\tif(-not (Test-Path -Path $configFilePath -PathType Leaf))\n\t{\n\t\t[System.Xml.XmlDocument]$document = New-Object System.Xml.XmlDocument\n\t\t\n\t\t# config file doesn't exist create a now one\n \t\t[System.Xml.XmlDeclaration]$prolog = $document.CreateXmlDeclaration(\"1.0\", \"utf-8\", $null)\n \t\t[System.Xml.XmlNode]$child = $document.AppendChild($prolog)\n\t\t[System.Xml.XmlElement]$configurationElement = Append-ElementIfNotExists $document $document.DocumentElement \"configuration\"\n\t\t\n\t\t# Save a copy of the document\n\t\t$document.Save($configFilePath)\n\t}\n}\n\nfunction Load-ConfigFile\n{\n\t[System.Xml.XmlDocument]$document = New-Object System.Xml.XmlDocument\n\t\n\t#Check if the document already exists and load it if it does not\n\tif(Test-Path -Path $configFilePath -PathType Leaf)\n\t{\n\t\t$document.Load($configFilePath)\n\t}\n\t\n\treturn $document\n}\n\nfunction Append-ElementIfNotExists\n{\n\tparam\n\t(\n\t\t[System.Xml.XmlDocument]$document,\n\t\t[System.Xml.XmlElement]$parent,\n\t\t[string]$elementName\n\t)\n\t[System.Xml.XmlElement]$element = $null\n\t[System.Xml.XmlNode]$parentNode = $parent\n\t\n\tif($document -ne $null)\n\t{\n\t\tif($parentNode -eq $null)\n\t\t{\n\t\t\t$parentNode = $document\n\t\t}\n\t\t\n\t\t$element = $parentNode.SelectSingleNode(\"./$($elementName)\")\n\t\t\n\t\tif($element -eq $null)\n\t\t{\n\t\t\t$element = $document.CreateElement($elementName)\n\t\t\t[System.Xml.XmlElement]$child = $parentNode.AppendChild($element)\n\t\t}\n\t}\n\t\n\treturn $element\n}\n\nfunction Create-ElementStructureIfNotExists\n{\n\tparam\n\t(\n\t\t[System.Xml.XmlDocument]$document\n\t)\n\t[bool]$isSuccess = $false\n\t\n\tif($document -ne $null)\n\t{\n\t\t[System.Xml.XmlElement]$configurationElement = Append-ElementIfNotExists $document $null \"configuration\"\n\t\t\n\t\tif($configurationElement -ne $null)\n\t\t{\n\t\t\t[System.Xml.XmlElement]$element = Append-ElementIfNotExists $document $configurationElement \"runtime\"\n\t\t\t\n\t\t\t$isSuccess = $element -ne $null\n\t\t}\n\t}\n\t\n\treturn $isSuccess\n}\n\n# Create the document if required\nCreate-ConfigFileIfNotExists\n\n# Load the configuration file into the XML document\n[System.Xml.XmlDocument]$configurationDocument = Load-ConfigFile\n\t\nif($configurationDocument -ne $null)\n{\n\tif(Create-ElementStructureIfNotExists $configurationDocument)\n\t{\n\t\t# All of the entries are on the runtime element\n\t\t[System.Xml.XmlElement]$runtimeElement = $configurationDocument.DocumentElement.SelectSingleNode('./runtime')\n\t\t\n\t\tif($runtimeElement -ne $null)\n\t\t{\n\t\t\t# Set the Server GC to enabled if requested\n\t\t\t[System.Xml.XmlElement]$serverGCElement = Append-ElementIfNotExists $configurationDocument $runtimeElement \"gcServer\"\n\t\t\t$serverGCElement.SetAttribute(\"enabled\", $serverGC.ToString([System.Globalization.CultureInfo]::InvariantCulture).ToLower()) \n\n\t\t\t# Set the concurrent GC to enabled if requested\n\t\t\t[System.Xml.XmlElement]$concurrentGCElement = Append-ElementIfNotExists $configurationDocument $runtimeElement \"gcConcurrent\"\n\t\t\t$concurrentGCElement.SetAttribute(\"enabled\", $backgroundGC.ToString([System.Globalization.CultureInfo]::InvariantCulture).ToLower()) \n\t\t}\n\t}\n\t\n\t# Save the document\n\t$configurationDocument.Save($configFilePath)\n}\n\n\n\n \n \n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.SingleCluster/SingleClusterRoleContent/ServerGC.cmd",
    "content": "﻿REM Check if the script is running in the Azure Emulator, and if so, do not run\nREM IF \"%IsEmulated%\"==\"true\" goto :EOF \nIf \"%UseServerGC%\"==\"False\" GOTO :ValidateBackground\nIf \"%UseServerGC%\"==\"0\" GOTO :ValidateBackground\n\nSET UseServerGC=\"True\"\n\n:ValidateBackground\nIf \"%UseBackgroundGC%\"==\"False\" GOTO :CommandExecution\nIf \"%UseBackgroundGC%\"==\"0\" GOTO :CommandExecution\nSET UseBackgroundGC=\"True\"\n\n:CommandExecution\nPowerShell.exe -executionpolicy unrestricted -command \".\\GCSettingsManagement.ps1\" -serverGC %UseServerGC% -backgroundGC %UseBackgroundGC%\n\nExit /b"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.SingleCluster/SingleClusterRoleContent/diagnostics.wadcfgx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<DiagnosticsConfiguration  xmlns=\"http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration\">\n  <PublicConfig>\n    <WadCfg>\n      <DiagnosticMonitorConfiguration overallQuotaInMB=\"4096\">\n        <DiagnosticInfrastructureLogs scheduledTransferLogLevelFilter=\"Error\"/>\n        <Logs scheduledTransferPeriod=\"PT1M\" scheduledTransferLogLevelFilter=\"Information\" />\n        <Directories scheduledTransferPeriod=\"PT1M\">\n          <IISLogs containerName =\"wad-iis-logfiles\" />\n          <FailedRequestLogs containerName =\"wad-failedrequestlogs\" />\n        </Directories>\n        <WindowsEventLog scheduledTransferPeriod=\"PT1M\" >\n          <DataSource name=\"Application!*[System[(Level=1 or Level=2 or Level=3)]]\" />\n          <DataSource name=\"Windows Azure!*[System[(Level=1 or Level=2 or Level=3 or Level=4)]]\" />\n        </WindowsEventLog>\n        <CrashDumps containerName=\"wad-crashdumps\" dumpType=\"Mini\">\n          <CrashDumpConfiguration processName=\"WaIISHost.exe\"/>\n          <CrashDumpConfiguration processName=\"WaWorkerHost.exe\"/>\n          <CrashDumpConfiguration processName=\"w3wp.exe\"/>\n        </CrashDumps>\n        <PerformanceCounters scheduledTransferPeriod=\"PT1M\">\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\Available MBytes\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Web Service(_Total)\\ISAPI Extension Requests/sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Web Service(_Total)\\Bytes Total/Sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET Applications(__Total__)\\Requests/Sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET Applications(__Total__)\\Errors Total/Sec\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET\\Requests Queued\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\ASP.NET\\Requests Rejected\" sampleRate=\"PT3M\" />\n          <PerformanceCounterConfiguration counterSpecifier=\"\\Processor(_Total)\\% Processor Time\" sampleRate=\"PT3M\" />\n        </PerformanceCounters>\n      </DiagnosticMonitorConfiguration>\n    </WadCfg>\n    <StorageAccount></StorageAccount>\n  </PublicConfig>\n  <PrivateConfig>\n    <StorageAccount name=\"\" key=\"\" endpoint=\"\" />\n  </PrivateConfig>\n  <IsEnabled>true</IsEnabled>\n</DiagnosticsConfiguration>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.Cloud.SingleCluster.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.25123.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Etg.Yams.WorkerRole\", \"Etg.Yams.WorkerRole\\Etg.Yams.WorkerRole.csproj\", \"{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}\"\nEndProject\nProject(\"{CC5FD16D-436D-48AD-A40C-5A424C6E3E79}\") = \"Etg.Yams.Cloud.SingleCluster\", \"Etg.Yams.Cloud.SingleCluster\\Etg.Yams.Cloud.SingleCluster.ccproj\", \"{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"SingleClusterRole\", \"SingleClusterRole\\SingleClusterRole.csproj\", \"{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F9C2B6E8-6D14-4201-956A-A2E93073CBBC}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tEnterpriseLibraryConfigurationToolBinariesPathV6 = packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.WorkerRole/Etg.Yams.WorkerRole.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProductVersion>8.0.30703</ProductVersion>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>{B38D7D2A-BDC1-49FE-B0DD-D799E3E746AD}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.WorkerRole</RootNamespace>\n    <AssemblyName>Etg.Yams.WorkerRole</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <SccProjectName>SAK</SccProjectName>\n    <SccLocalPath>SAK</SccLocalPath>\n    <SccAuxPath>SAK</SccAuxPath>\n    <SccProvider>SAK</SccProvider>\n    <RoleType>Worker</RoleType>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Label=\"SlowCheetah\">\n    <SlowCheetahToolsPath>$([System.IO.Path]::GetFullPath( $(MSBuildProjectDirectory)\\..\\packages\\SlowCheetah.2.5.14\\tools\\))</SlowCheetahToolsPath>\n    <SlowCheetah_EnableImportFromNuGet Condition=\" '$(SlowCheetah_EnableImportFromNuGet)'=='' \">true</SlowCheetah_EnableImportFromNuGet>\n    <SlowCheetah_NuGetImportPath Condition=\" '$(SlowCheetah_NuGetImportPath)'=='' \">$([System.IO.Path]::GetFullPath( $(MSBuildProjectDirectory)\\Properties\\SlowCheetah\\SlowCheetah.Transforms.targets ))</SlowCheetah_NuGetImportPath>\n    <SlowCheetahTargets Condition=\" '$(SlowCheetah_EnableImportFromNuGet)'=='true' and Exists('$(SlowCheetah_NuGetImportPath)') \">$(SlowCheetah_NuGetImportPath)</SlowCheetahTargets>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.0.14\\lib\\net451\\Etg.Yams.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.AzureBlobStorageDeploymentRepository, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.0.14\\lib\\net451\\Etg.Yams.AzureBlobStorageDeploymentRepository.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.AzureBlobStorageUpdateSession, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.0.14\\lib\\net451\\Etg.Yams.AzureBlobStorageUpdateSession.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.AzureUtils, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.0.14\\lib\\net451\\Etg.Yams.AzureUtils.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.0.14\\lib\\net451\\Etg.Yams.Common.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.0.14\\lib\\net451\\Etg.Yams.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Edm.5.6.4\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.OData.5.6.4\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Services.Client.5.6.4\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Diagnostics, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\">\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.ServiceRuntime, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\">\n      <Private>False</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\WindowsAzure.Storage.7.0.0\\lib\\net40\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <SpecificVersion>False</SpecificVersion>\n      <HintPath>..\\packages\\Microsoft.AspNet.WebApi.Client.5.2.3\\lib\\net45\\System.Net.Http.Formatting.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Rx-Core.2.2.5\\lib\\net45\\System.Reactive.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Rx-Interfaces.2.2.5\\lib\\net45\\System.Reactive.Interfaces.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Rx-Linq.2.2.5\\lib\\net45\\System.Reactive.Linq.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Rx-PlatformServices.2.2.5\\lib\\net45\\System.Reactive.PlatformServices.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Spatial.5.6.4\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Web.Cors, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <SpecificVersion>False</SpecificVersion>\n      <HintPath>..\\packages\\Microsoft.AspNet.Cors.5.2.3\\lib\\net45\\System.Web.Cors.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <SpecificVersion>False</SpecificVersion>\n      <HintPath>..\\packages\\Microsoft.AspNet.WebApi.Core.5.2.3\\lib\\net45\\System.Web.Http.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Web.Http.Owin\">\n      <HintPath>..\\packages\\Microsoft.AspNet.WebApi.Owin.5.2.3\\lib\\net45\\System.Web.Http.Owin.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Utils\\AzureUtils.cs\" />\n    <Compile Include=\"Utils\\DeploymentIdUtils.cs\" />\n    <Compile Include=\"WorkerRoleConfig.cs\" />\n    <Compile Include=\"WorkerRole.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\">\n      <SubType>Designer</SubType>\n    </None>\n    <None Include=\"packages.config\">\n      <SubType>Designer</SubType>\n    </None>\n    <None Include=\"Properties\\SlowCheetah\\SlowCheetah.Transforms.targets\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n  <UsingTask TaskName=\"TransformXml\" AssemblyFile=\"$(MSBuildExtensionsPath32)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)\\Web\\Microsoft.Web.Publishing.Tasks.dll\" />\n  <Target Name=\"AfterCompile\" Condition=\"Exists('app.$(Configuration).config')\">\n    <!--Generate transformed app config in the intermediate directory-->\n    <TransformXml Source=\"app.config\" Destination=\"$(IntermediateOutputPath)$(TargetFileName).config\" Transform=\"app.$(Configuration).config\" />\n    <!--Force build process to use the transformed configuration file from now on.-->\n    <ItemGroup>\n      <AppConfigWithTargetPath Remove=\"app.config\" />\n      <AppConfigWithTargetPath Include=\"$(IntermediateOutputPath)$(TargetFileName).config\">\n        <TargetPath>$(TargetFileName).config</TargetPath>\n      </AppConfigWithTargetPath>\n    </ItemGroup>\n  </Target>\n  <!--Override After Publish to support ClickOnce AfterPublish. Target replaces the untransformed config file copied to the deployment directory with the transformed one.-->\n  <Target Name=\"AfterPublish\">\n    <PropertyGroup>\n      <DeployedConfig>$(_DeploymentApplicationDir)$(TargetName)$(TargetExt).config$(_DeploymentFileMappingExtension)</DeployedConfig>\n    </PropertyGroup>\n    <!--Publish copies the untransformed App.config to deployment directory so overwrite it-->\n    <Copy Condition=\"Exists('$(DeployedConfig)')\" SourceFiles=\"$(IntermediateOutputPath)$(TargetFileName).config\" DestinationFiles=\"$(DeployedConfig)\" />\n  </Target>\n  <Import Project=\"$(SlowCheetahTargets)\" Condition=\"Exists('$(SlowCheetahTargets)')\" Label=\"SlowCheetah\" />\n</Project>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.WorkerRole/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Etg.Yams.WorkerRole\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Etg.Yams.WorkerRole\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2015\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"3c42c4c6-7764-4559-967b-b8861a3856fb\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.WorkerRole/Properties/SlowCheetah/SlowCheetah.Transforms.targets",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n***********************************************************************************************\nSlowCheetah.Transforms.targets\n\nWARNING:  DO NOT MODIFY this file, this file is added to your project automatically\n          through the SlowCheetah NuGet package. If you modify this file it may\n          get out of sync when you update the package at a later date.\n\nThis file defines the steps in order to transform XML files.\n\nCopyright (C) Sayed Ibrahim Hashimi, Chuck England 2011-2013. All rights reserved.\n***********************************************************************************************\n-->\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\n  <PropertyGroup>\n    <sc-MSBuildLibPathLocal Condition=\" '$(sc-MSBuildLibPathLocal)'=='' \">$(LocalAppData)\\Microsoft\\MSBuild\\SlowCheetah\\v2.5.11\\</sc-MSBuildLibPathLocal>\n\n    <!-- this property should be defined in the .csproj to point to the packages path -->\n    <SlowCheetahToolsPath Condition=\" '$(SlowCheetahToolsPath)'=='' \">$(MSBuildThisFileDirectory)</SlowCheetahToolsPath>\n\n    <!-- if building in VS then we should try and use from app data if the files are there -->\n    <SlowCheetahTaskPath Condition=\" '$(SlowCheetahTaskPath)'=='' and '$(BuildingInsideVisualStudio)'=='true' and Exists('$(sc-MSBuildLibPathLocal)SlowCheetah.Xdt.dll')\">$(sc-MSBuildLibPathLocal)</SlowCheetahTaskPath>\n\n    <!-- this typically points to the packages folder -->\n    <SlowCheetahTaskPath Condition=\" '$(SlowCheetahTaskPath)'==''\">$(SlowCheetahToolsPath)</SlowCheetahTaskPath>\n  </PropertyGroup>\n  <ItemGroup>\n    <LocalAppDataFiles Include=\"$(sc-MSBuildLibPathLocal)**\\*\" />\n  </ItemGroup>\n\n  <Target Name=\"CopyAssembliesToLocalPath\"\n          Condition=\" '$(sc-MSBuildLibPathLocal)'!='' and ( !Exists('$(sc-MSBuildLibPathLocal)') or '@(LocalAppDataFiles)'=='' )\">\n    <ItemGroup>\n      <_FilesToCopy Remove=\"@(_FilesToCopy)\"/>\n      <_FilesToCopy Include=\"$(SlowCheetahToolsPath)Microsoft.Web.XmlTransform.dll\"/>\n      <_FilesToCopy Include=\"$(SlowCheetahToolsPath)SlowCheetah.NuGet.template.proj\"/>\n      <_FilesToCopy Include=\"$(SlowCheetahToolsPath)SlowCheetah.Transforms.targets\"/>\n      <_FilesToCopy Include=\"$(SlowCheetahToolsPath)SlowCheetah.Xdt.dll\"/>\n    </ItemGroup>\n\n    <MakeDir Directories=\"$(sc-MSBuildLibPathLocal)\" ContinueOnError=\"true\"/>\n    <Message Text=\"Copying SlowCheetah build files to [$(sc-MSBuildLibPathLocal)] if needed\" />\n    <Message Text=\"SlowCheetahToolsPath: $(SlowCheetahToolsPath)\" Importance=\"low\" />\n    <Message Text=\"************ %40(_FilesToCopy): [@(_FilesToCopy)]\" Importance=\"low\"/>\n\n    <!-- If the copy does not succeed then we need to revert back to the packages folder -->\n    <Copy SourceFiles=\"@(_FilesToCopy)\"\n          DestinationFiles=\"@(_FilesToCopy->'$(sc-MSBuildLibPathLocal)%(RecursiveDir)%(Filename)%(Extension)')\"\n          SkipUnchangedFiles=\"true\" ContinueOnError=\"true\"\n          Condition=\"Exists('%(_FilesToCopy.FullPath)')\" />\n\n    <PropertyGroup>\n      <sc-MSBuildLibPathLocal Condition=\" !Exists('$(sc-MSBuildLibPathLocal)Microsoft.Web.XmlTransform.dll') \">$(SlowCheetahToolsPath)</sc-MSBuildLibPathLocal>\n    </PropertyGroup>\n    <Message Text=\"SlowCheetah tools path: sc-MSBuildLibPathLocal: [$(sc-MSBuildLibPathLocal)]\" />\n  </Target>\n\n  <UsingTask TaskName=\"TransformXml\"\n             AssemblyFile=\"$([MSBUILD]::Unescape($(SlowCheetahTaskPath)SlowCheetah.Xdt.dll))\"/>\n  <ItemDefinitionGroup>\n    <!-- Set the default value to false here -->\n    <None>\n      <TransformOnBuild>false</TransformOnBuild>\n      <Link></Link>\n    </None>\n    <Content>\n      <TransformOnBuild>false</TransformOnBuild>\n      <Link></Link>\n    </Content>\n    <Resource>\n      <TransformOnBuild>false</TransformOnBuild>\n      <Link></Link>\n    </Resource>\n    <EmbeddedResource>\n      <TransformOnBuild>false</TransformOnBuild>\n      <Link></Link>\n    </EmbeddedResource>\n\n    <_FilesToTransform>\n      <IsAppConfig>false</IsAppConfig>\n    </_FilesToTransform>\n  </ItemDefinitionGroup>\n\n  <PropertyGroup>\n    <WapProjectTypeGuid>349c5851-65df-11da-9384-00065b846f21</WapProjectTypeGuid>\n    <_IsWap Condition=\" '$(WapProjectTypeGuid)' != '' and '$(ProjectTypeGuids)' != '' \">$(ProjectTypeGuids.Contains($(WapProjectTypeGuid)))</_IsWap>\n    <_IsWap Condition=\" '$(_IsWap)' == '' \">false</_IsWap>\n    <IsWap Condition=\" '$(IsWap)' == ''\">$(_IsWap)</IsWap>\n\n    <ScAllowCopyReferencedConfig Condition=\" '$(ScAllowCopyReferencedConfig)'=='' \">true</ScAllowCopyReferencedConfig>\n    <AllowedReferenceRelatedFileExtensions Condition=\" '$(ScAllowCopyReferencedConfig)'=='true' \">\n      $(AllowedReferenceRelatedFileExtensions);\n      .dll.config\n    </AllowedReferenceRelatedFileExtensions>\n\n    <SlowCheetahImport>$(MSBuildThisFileFullPath)</SlowCheetahImport>\n    <BuildDependsOn>\n      CopyAssembliesToLocalPath;\n      $(BuildDependsOn);\n    </BuildDependsOn>\n    <BuildDependsOn Condition=\" '$(IsWap)'!='true' \">\n      $(BuildDependsOn);\n      TransformAllFiles;\n      ScReplaceAppConfigItem;\n    </BuildDependsOn>\n    <!--<TransformAllFilesDependsOn>\n      _CopyAppConfigFile;\n      DiscoverFilesToTransform;\n    </TransformAllFilesDependsOn>-->\n    <TransformAllFilesDependsOn>\n      CopyAssembliesToLocalPath;\n      DiscoverFilesToTransform;\n    </TransformAllFilesDependsOn>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <__SC_IntermediateAppConfig>$(IntermediateOutputPath)$(MSBuildProjectFile)-sc.App.config</__SC_IntermediateAppConfig>\n  </PropertyGroup>\n\n  <Target Name=\"TransformAllFiles\"\n          DependsOnTargets=\"$(TransformAllFilesDependsOn)\" BeforeTargets=\"_CopyAppConfigFile\">\n    <!-- Now we have the item list _FilesToTransformNotAppConfig and _AppConfigToTransform item lists -->\n    <!-- Transform the app.config file -->\n    <ItemGroup>\n      <_AppConfigTarget Include=\"@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')\" />\n    </ItemGroup>\n\n    <PropertyGroup>\n      <_AppConfigDest>@(_AppConfigTarget->'%(FullPath)')</_AppConfigDest>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <_TmpLinkFiles Remove=\"@(_TmpLinkFiles)\" />\n      <_TmpLinkFiles Include=\"@(_FilesToTransformNotAppConfig->'%(Link)')\" />\n    </ItemGroup>\n\n    <!-- This will handle non Link files and the second one for link files -->\n    <MakeDir Directories=\"@(_FilesToTransformNotAppConfig->'$(OutDir)%(RelativeDir)')\"\n             Condition=\"Exists('%(RelativeDir)%(Filename).$(Configuration)%(Extension)')\n             and '%(Link)'=='' \" />\n\n    <MakeDir Directories=\"@(_TmpLinkFiles->'$(OutDir)%(RelativeDir)')\"\n                 Condition=\" '%(Link)'!='' \" />\n\n    <PropertyGroup>\n      <_Sc_HasAppConfigTransform>false</_Sc_HasAppConfigTransform>\n      <_Sc_HasAppConfigConfigurationTransform Condition=\" Exists( '@(_AppConfigToTransform->'%(RelativeDir)%(Filename).$(Configuration)%(Extension)')' ) \">true</_Sc_HasAppConfigConfigurationTransform>\n      <_Sc_HasAppConfigPublishProfileTransform Condition=\" Exists( '@(_AppConfigToTransform->'%(RelativeDir)%(Filename).$(PublishProfile)%(Extension)')' ) \">true</_Sc_HasAppConfigPublishProfileTransform>\n      <_Sc_HasAppConfigPublishProfileTransform Condition=\" '$(Configuration)'=='$(PublishProfile)' \">false</_Sc_HasAppConfigPublishProfileTransform>\n      <_Sc_HasAppConfigTransform Condition=\" '$(_Sc_HasAppConfigConfigurationTransform)'=='true' \">true</_Sc_HasAppConfigTransform>\n      <_Sc_HasAppConfigTransform Condition=\" '$(_Sc_HasAppConfigPublishProfileTransform)'=='true' \">true</_Sc_HasAppConfigTransform>\n    </PropertyGroup>\n    <Message Text=\"Tasks path: $(SlowCheetahTaskPath)\" Importance=\"low\"/>\n\n    <!-- we may transform the file multiple times so copy it to dest and then use that as source for all transforms -->\n    <Copy SourceFiles=\"$(AppConfig)\" DestinationFiles=\"$(__SC_IntermediateAppConfig)\"/>\n\n    <SlowCheetah.Xdt.TransformXml Source=\"$(__SC_IntermediateAppConfig)\"\n                  Transform=\"@(_AppConfigToTransform->'%(RelativeDir)%(Filename).$(Configuration)%(Extension)')\"\n                  Destination=\"$(__SC_IntermediateAppConfig)\"\n                  Condition=\" '$(_Sc_HasAppConfigConfigurationTransform)'=='true' \" />\n\n    <SlowCheetah.Xdt.TransformXml Source=\"$(__SC_IntermediateAppConfig)\"\n                  Transform=\"@(_AppConfigToTransform->'%(RelativeDir)%(Filename).$(PublishProfile)%(Extension)')\"\n                  Destination=\"$(__SC_IntermediateAppConfig)\"\n                  Condition=\" '$(_Sc_HasAppConfigPublishProfileTransform)'=='true' \" />\n\n    <PropertyGroup Condition=\" '$(_Sc_HasAppConfigTransform)'=='true' \" >\n      <AppConfig>$(__SC_IntermediateAppConfig)</AppConfig>\n    </PropertyGroup>\n    <ItemGroup Condition=\" '$(_Sc_HasAppConfigTransform)'=='true' \" >\n      <AppConfigWithTargetPath Remove=\"@(AppConfigWithTargetPath)\" />\n      <AppConfigWithTargetPath Include=\"$(AppConfig)\">\n        <TargetPath>$(TargetFileName).config</TargetPath>\n      </AppConfigWithTargetPath>\n    </ItemGroup>\n\n    <!-- \n    For link files this will write the transformed file into the \n    incorrect location so let's handle those seperately in the transformation underneath this one\n    -->\n    <SlowCheetah.Xdt.TransformXml Source=\"@(_FilesToTransformNotAppConfig->'%(FullPath)')\"\n                  Transform=\"%(RelativeDir)%(Filename).$(Configuration)%(Extension)\"\n                  Destination=\"@(_FilesToTransformNotAppConfig->'$(OutDir)%(RelativeDir)%(Filename)%(Extension)')\"\n                  Condition=\" Exists('%(RelativeDir)%(Filename).$(Configuration)%(Extension)')\n                              and '%(Link)'=='' \" />\n\n    <!-- Transform the Link files -->\n    <SlowCheetah.Xdt.TransformXml Source=\"@(_FilesToTransformNotAppConfig->'%(FullPath)')\"\n                  Transform=\"%(RelativeDir)%(Filename).$(Configuration)%(Extension)\"\n                  Destination=\"@(_FilesToTransformNotAppConfig->'$(OutDir)%(Link)')\"\n                  Condition=\"Exists('%(RelativeDir)%(Filename).$(Configuration)%(Extension)')\n                              and '%(Link)'!='' \" />\n  </Target>\n\n  <Target Name=\"DiscoverFilesToTransform\">\n    <!-- \n    This will look through items list: None & Content for those\n    with Metadata <TransformOnBuild>True</TransformOnBuild>.\n    \n    -->\n    <ItemGroup>\n      <_FilesToTransform Include=\"@(None);@(Content);@(Resource);@(EmbeddedResource)\"\n                         Condition=\" '%(TransformOnBuild)' == 'true' \">\n        <Link>%(Link)</Link>\n        <!-- Required to remove the item if necessary later -->\n        <OriginalItemSpec>%(Identity)</OriginalItemSpec>\n      </_FilesToTransform>\n    </ItemGroup>\n\n    <PropertyGroup>\n      <_AppConfigFullPath>@(AppConfigWithTargetPath->'%(RootDir)%(Directory)%(Filename)%(Extension)')</_AppConfigFullPath>\n    </PropertyGroup>\n\n    <!-- Now look to see if any of these are the app.config file -->\n    <ItemGroup>\n      <_FilesToTransform Condition=\" '%(Filename)%(Extension)'=='app.config' \">\n        <IsAppConfig>true</IsAppConfig>\n        <!-- Required to remove the item if necessary later -->\n        <OriginalItemSpec>%(Identity)</OriginalItemSpec>\n      </_FilesToTransform>\n    </ItemGroup>\n\n    <ItemGroup>\n      <_FilesToTransformNotAppConfig Include=\"@(_FilesToTransform)\"\n                                     Condition=\" '%(IsAppConfig)'!='true'\">\n        <!-- Required to remove the item if necessary later -->\n        <OriginalItemSpec>%(Identity)</OriginalItemSpec>\n        <Link>%(_FilesToTransform.Link)</Link>\n      </_FilesToTransformNotAppConfig>\n\n      <_AppConfigToTransform  Include=\"@(_FilesToTransform)\"\n                              Condition=\" '%(IsAppConfig)'=='true'\"/>\n    </ItemGroup>\n  </Target>\n\n\n  <!-- ***********************************************************\n  WAP related items below\n  ****************************************************************-->\n  <ItemGroup>\n    <!-- This will exclude packageRestore.proj from the web publish process -->\n    <ExcludeFromPackageFiles Include=\"packageRestore.proj\">\n      <FromTarget>Project</FromTarget>\n    </ExcludeFromPackageFiles>\n  </ItemGroup>\n\n  <PropertyGroup Condition=\" '$(IsWap)' == 'true' \">\n    <OnAfterPipelinePreDeployCopyAllFilesToOneFolder>\n      $(OnAfterPipelinePreDeployCopyAllFilesToOneFolder);\n      CopyTransformFilesWap;\n    </OnAfterPipelinePreDeployCopyAllFilesToOneFolder>\n    <CopyAllFilesToSingleFolderForMsdeploy>\n      $(CopyAllFilesToSingleFolderForMsdeploy);\n      CopyTransformFilesWap;\n    </CopyAllFilesToSingleFolderForMsdeploy>\n\n    <CopyTransformFilesWapDependsOn>\n      CoreCopyTransformFilesWap;\n      CopyTransformFileWapPublishProfile;\n    </CopyTransformFilesWapDependsOn>\n\n    <CoreCopyTransformFilesWapDependsOn>\n      DiscoverFilesToTransform;\n    </CoreCopyTransformFilesWapDependsOn>\n\n    <!-- For VS2012 -->\n    <PipelineCopyAllFilesToOneFolderForMsdeployDependsOn>\n      $(PipelineCopyAllFilesToOneFolderForMsdeployDependsOn);\n      CopyTransformFilesWap\n    </PipelineCopyAllFilesToOneFolderForMsdeployDependsOn>\n\n    <!-- Required for File System -->\n    <PipelinePreDeployCopyAllFilesToOneFolderDependsOn>\n      $(PipelinePreDeployCopyAllFilesToOneFolderDependsOn);\n      CopyTransformFilesWap;\n    </PipelinePreDeployCopyAllFilesToOneFolderDependsOn>\n    <!-- required for FS support from the VS publish dialog -->\n    <OnAfterCopyAllFilesToSingleFolderForPackage>\n      $(OnAfterCopyAllFilesToSingleFolderForPackage);\n      CopyTransformFilesWap;\n    </OnAfterCopyAllFilesToSingleFolderForPackage>\n  </PropertyGroup>\n  <Target Name=\"CopyTransformFilesWap\" DependsOnTargets=\"$(CopyTransformFilesWapDependsOn)\"/>\n  <Target Name=\"CoreCopyTransformFilesWap\"\n          DependsOnTargets=\"$(CoreCopyTransformFilesWapDependsOn)\">\n    <ItemGroup>\n      <_TmpLinkFiles Remove=\"@(_TmpLinkFiles)\" />\n      <_TmpLinkFiles Include=\"@(_FilesToTransformNotAppConfig->'%(Link)')\" />\n    </ItemGroup>\n\n    <!-- This will ignore link files and the second one will handle them -->\n    <MakeDir Directories=\"@(_FilesToTransformNotAppConfig->'$(_PackageTempDir)\\%(RelativeDir)')\"\n         Condition=\"Exists('%(RelativeDir)%(Filename).$(Configuration)%(Extension)')\n                    and '%(Link)' == '' \"/>\n\n    <MakeDir Directories=\"@(_TmpLinkFiles->'$(OutDir)%(RelativeDir)')\"\n                 Condition=\" '%(Link)'!='' \" />\n\n    <!--Make sure that we do not do this for web.config-->\n    <!-- This usage will skip Link files, the task usage below will handle Link files -->\n    <SlowCheetah.Xdt.TransformXml Source=\"@(_FilesToTransformNotAppConfig->'%(FullPath)')\"\n              Transform=\"%(RelativeDir)%(Filename).$(Configuration)%(Extension)\"\n              Destination=\"@(_FilesToTransformNotAppConfig->'$(_PackageTempDir)\\%(RelativeDir)%(Filename)%(Extension)')\"\n              Condition=\" '%(Filename)%(Extension)' != 'web.config' and\n                          Exists('%(RelativeDir)%(Filename).$(Configuration)%(Extension)')\n                          and '%(Link)'=='' \" />\n\n    <!-- Transform the Link files, they always go into the root directory -->\n    <SlowCheetah.Xdt.TransformXml Source=\"@(_FilesToTransformNotAppConfig->'%(FullPath)')\"\n              Transform=\"%(RelativeDir)%(Filename).$(Configuration)%(Extension)\"\n              Destination=\"@(_FilesToTransformNotAppConfig->'$(_PackageTempDir)\\%(Link)')\"\n              Condition=\" '%(Filename)%(Extension)' != 'web.config' and\n                          Exists('%(RelativeDir)%(Filename).$(Configuration)%(Extension)')\n                          and '%(Link)'!='' \" />\n  </Target>\n\n  <Target Name=\"CopyTransformFileWapPublishProfile\" DependsOnTargets=\"CoreCopyTransformFilesWap\">\n    <ItemGroup>\n      <_ScWapPubProfileFullPath Include=\"$(WebPublishProfileFile)\"/>\n    </ItemGroup>\n    <PropertyGroup>\n      <_WapPubProfile Condition=\" '$(_WapPubProfile)'=='' and '@(_ScWapPubProfileFullPath)'!='' \">%(_ScWapPubProfileFullPath.Filename)</_WapPubProfile>\n    </PropertyGroup>\n\n    <!--Make sure that we do not do this for web.config-->\n    <!-- This usage will skip Link files, the task usage below will handle Link files -->\n    <SlowCheetah.Xdt.TransformXml Source=\"@(_FilesToTransformNotAppConfig->'$(_PackageTempDir)\\%(RelativeDir)%(Filename)%(Extension)')\"\n              Transform=\"%(RelativeDir)%(Filename).$(_WapPubProfile)%(Extension)\"\n              Destination=\"@(_FilesToTransformNotAppConfig->'$(_PackageTempDir)\\%(RelativeDir)%(Filename)%(Extension)')\"\n              Condition=\" '%(Filename)%(Extension)' != 'web.config' and\n                          Exists('%(RelativeDir)%(Filename).$(_WapPubProfile)%(Extension)')\n                          and '%(Link)'=='' and '$(_WapPubProfile)'!='' and '$(_WapPubProfile)'!='$(Configuration)' \" />\n\n    <!-- Transform the Link files, they always go into the root directory -->\n    <SlowCheetah.Xdt.TransformXml Source=\"@(_FilesToTransformNotAppConfig->'$(_PackageTempDir)\\%(Link)')\"\n              Transform=\"%(RelativeDir)%(Filename).$(_WapPubProfile)%(Extension)\"\n              Destination=\"@(_FilesToTransformNotAppConfig->'$(_PackageTempDir)\\%(Link)')\"\n              Condition=\" '%(Filename)%(Extension)' != 'web.config' and\n                          Exists('%(RelativeDir)%(Filename).$(_WapPubProfile)%(Extension)')\n                          and '%(Link)'!=''  and '$(_WapPubProfile)'!='' and '$(_WapPubProfile)'!='$(Configuration)' \" />\n  </Target>\n\n  <!-- ***********************************************************\n  ClickOnce related items below\n  ****************************************************************-->\n\n  <!-- Target was named: SlowCheetah_ClickOnceUpdate -->\n  <Target Name=\"ScReplaceAppConfigItem\"\n          BeforeTargets=\"_DeploymentComputeClickOnceManifestInfo;BuiltProjectOutputGroup\"\n          DependsOnTargets=\"TransformAllFiles\">\n    <!--<Message Text=\"ScReplaceAppConfigItem\" Importance=\"low\"/>\n    <PropertyGroup>\n      <_SlowCheetahAppConfigTransformExists Condition=\"Exists(@(_AppConfigToTransform->'%(RelativeDir)%(Filename).$(Configuration)%(Extension)'))\">true</_SlowCheetahAppConfigTransformExists>\n    </PropertyGroup>\n    <PropertyGroup>\n      <_OldAppConfigWithTargetPath>%(AppConfigWithTargetPath.TargetPath)</_OldAppConfigWithTargetPath>\n      <_SCNewAppConfigFile>@(AppConfigWithTargetPath->'$(IntermediateOutputPath)SlowCheetah\\%(Filename)%(Extension)')</_SCNewAppConfigFile>\n      <_TmpFileExist>false</_TmpFileExist>\n      <_TmpFileExist Condition=\"Exists('@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')')\">true</_TmpFileExist>\n    </PropertyGroup>\n    <Message Text=\"****_TmpFileExis: [$(_TmpFileExist)]\" Importance=\"high\"/>\n    <Copy SourceFiles=\"@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')\" \n          DestinationFiles=\"$(_SCNewAppConfigFile)\" \n          Condition=\"'$(_SlowCheetahAppConfigTransformExists)'=='true' and Exists('@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')')\" />\n    \n    <ItemGroup Condition=\"'$(_SlowCheetahAppConfigTransformExists)'=='true'\">\n      <AppConfigWithTargetPath Remove=\"@(AppConfigWithTargetPath)\" />\n      <AppConfigWithTargetPath Include=\"$(_SCNewAppConfigFile)\">\n        <TargetPath>$(_OldAppConfigWithTargetPath)</TargetPath>\n      </AppConfigWithTargetPath>\n    </ItemGroup>\n\n    <Message Text=\"Updated app.config to point to transformed file\" />\n    <Message Text=\"    AppConfigWithTargetPath: @(AppConfigWithTargetPath)\"/>\n    <Message Text=\"    AppConfigWithTargetPath.TargetPath: @(AppConfigWithTargetPath->'%(TargetPath)')\"/>-->\n\n  </Target>\n\n  <Target Name=\"SlowCheetah_ClickOnceLooseFileUpdate\" AfterTargets=\"_DeploymentComputeClickOnceManifestInfo\" DependsOnTargets=\"DiscoverFilesToTransform\">\n    <!-- For non app.config files which are being transformed we need to remove the original item and replace it with the transformed one -->\n    <ItemGroup>\n      <_DeploymentManifestFiles Remove=\"%(_FilesToTransformNotAppConfig.OriginalItemSpec)\" />\n      <!-- Implementation for non-Link files -->\n      <_DeploymentManifestFiles Include=\"@(_FilesToTransformNotAppConfig->'$(OutDir)%(RelativeDir)%(Filename)%(Extension)')\"\n                                Condition=\" '%(_FilesToTransformNotAppConfig.Link)'=='' \">\n        <TargetPath Condition=\" '%(_FilesToTransformNotAppConfig.Link)'=='' \">%(RelativeDir)%(Filename)%(Extension)</TargetPath>\n      </_DeploymentManifestFiles>\n\n      <!-- Implementation for Linked files -->\n      <_DeploymentManifestFiles Include=\"@(_FilesToTransformNotAppConfig->'$(OutDir)%(Link)')\"\n                                Condition=\" '%(_FilesToTransformNotAppConfig.Link)'!='' \">\n        <TargetPath>%(_FilesToTransformNotAppConfig.Link)</TargetPath>\n      </_DeploymentManifestFiles>\n    </ItemGroup>\n  </Target>\n\n\n  <!-- ***********************************************************\n  Setup project related items below\n  ****************************************************************-->\n  <PropertyGroup>\n    <SlowCheetahEnableSetupProjects Condition=\" '$(SlowCheetahEnableSetupProjects)'=='' \">true</SlowCheetahEnableSetupProjects>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\" '$(SlowCheetahEnableSetupProjects)'=='true'\">\n    <AddAppConfigToBuildOutputs>false</AddAppConfigToBuildOutputs>\n\n    <BuiltProjectOutputGroupDependsOn>\n      $(BuiltProjectOutputGroupDependsOn);\n      AfterBuiltProjectOutputGroup\n    </BuiltProjectOutputGroupDependsOn>\n  </PropertyGroup>\n\n  <Target Name=\"AfterBuiltProjectOutputGroup\" DependsOnTargets=\"TransformAllFiles\">\n\n    <ItemGroup>\n      <_TmpAppConfig Include=\"@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')\" />\n    </ItemGroup>\n\n    <!-- We need to get the full path to the files included in the Identiy metadata.\n         This is required for Worker Roles. The target CopyWorkerRoleFiles attempts to copy but\n         does not use the FullPath so it will not locate the files otherwise.\n         See https://github.com/sayedihashimi/slow-cheetah/issues/44.\n    -->\n    <ItemGroup>\n      <_FilesToTransformNotAppConfig>\n        <FullPathToItem Condition=\" '%(Link)'=='' \">$([System.IO.Path]::GetFullPath( $(OutDir)%(RelativeDir)%(Filename)%(Extension) ))</FullPathToItem>\n        <FullPathToItem Condition=\" '%(Link)'!='' \">$([System.IO.Path]::GetFullPath( $(OutDir)%(Link) ))</FullPathToItem>\n      </_FilesToTransformNotAppConfig>\n    </ItemGroup>\n\n    <ItemGroup>\n      <BuiltProjectOutputGroupOutput Include=\"@(_TmpAppConfig->'%(FullPath)')\">\n        <!-- For compatibility with 2.0 -->\n        <OriginalItemSpec>$(AppConfig)</OriginalItemSpec>\n      </BuiltProjectOutputGroupOutput>\n\n      <BuiltProjectOutputGroupOutput Include=\"@(_FilesToTransformNotAppConfig->'%(FullPathToItem)')\"\n                                     Condition=\" '%(_FilesToTransformNotAppConfig.Link)'==''\">\n        <OriginalItemSpec>@(_FilesToTransformNotAppConfig->'$(OutDir)%(RelativeDir)%(Filename)%(Extension)')</OriginalItemSpec>\n        <TargetPath>@(_FilesToTransformNotAppConfig->'%(RelativeDir)%(Filename)%(Extension)')</TargetPath>\n      </BuiltProjectOutputGroupOutput>\n\n      <BuiltProjectOutputGroupOutput Include=\"@(_FilesToTransformNotAppConfig->'%(FullPathToItem)')\"\n                                     Condition=\" '%(_FilesToTransformNotAppConfig.Link)'!=''\">\n        <OriginalItemSpec>@(_FilesToTransformNotAppConfig->'$(OutDir)%(Link)')</OriginalItemSpec>\n        <TargetPath>@(_FilesToTransformNotAppConfig->'%(Link)')</TargetPath>\n      </BuiltProjectOutputGroupOutput>\n    </ItemGroup>\n\n    <!--<Message Text=\"OutDir: $(Outdir)\" Importance=\"high\"/>\n    <Message Text=\"BuiltProjectOutputGroupOutput: [%(BuiltProjectOutputGroupOutput.Identity),%(BuiltProjectOutputGroupOutput.TargetPath)]\" Importance=\"high\"/>-->\n  </Target>\n</Project>\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.WorkerRole/Utils/AzureUtils.cs",
    "content": "﻿using Microsoft.WindowsAzure.ServiceRuntime;\n\nnamespace Etg.Yams.WorkerRole.Utils\n{\n    public static class AzureUtils\n    {\n        public static bool IsEmulator()\n        {\n            return RoleEnvironment.IsAvailable && RoleEnvironment.IsEmulated;\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.WorkerRole/Utils/DeploymentIdUtils.cs",
    "content": "﻿using Microsoft.WindowsAzure.ServiceRuntime;\n\nnamespace Etg.Yams.WorkerRole.Utils\n{\n    public static class DeploymentIdUtils\n    {\n        public static string GetYamsClusterId(bool isSingleClusterDeployment)\n        {\n            if (!RoleEnvironment.IsAvailable)\n            {\n                return Constants.TestDeploymentId;\n            }\n\n            string deploymentId = RoleEnvironment.IsEmulated\n                ? Constants.TestDeploymentId\n                : RoleEnvironment.DeploymentId;\n\n            if (isSingleClusterDeployment)\n            {\n                return deploymentId;\n            }\n\n            // This concatenates the Cloud Service deployment id and the role name so that there is a unique name for each role in the Cloud Service\n            return $\"{deploymentId}_{RoleEnvironment.CurrentRoleInstance.Role.Name}\";\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.WorkerRole/WorkerRole.cs",
    "content": "using System;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Net;\nusing System.Security.Permissions;\nusing System.Threading.Tasks;\nusing Etg.Yams.WorkerRole.Utils;\nusing Microsoft.WindowsAzure.ServiceRuntime;\n\nnamespace Etg.Yams.WorkerRole\n{\n    public class YamsWorkerRole : RoleEntryPoint\n    {\n        private IYamsService _yamsService;\n\n        protected virtual bool IsSingleClusterDeployment\n        {\n            get { return true; }\n        }\n\n        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]\n        public override void Run()\n        {\n            RunAsync().Wait();\n        }\n\n        public async Task RunAsync()\n        {\n            WorkerRoleConfig config = new WorkerRoleConfig();\n            YamsConfig yamsConfig = new YamsConfigBuilder(\n                // mandatory configs\n                DeploymentIdUtils.GetYamsClusterId(this.IsSingleClusterDeployment),\n                RoleEnvironment.CurrentRoleInstance.UpdateDomain.ToString(),\n                RoleEnvironment.CurrentRoleInstance.Id,\n                config.CurrentRoleInstanceLocalStoreDirectory)\n                // optional configs\n                .SetCheckForUpdatesPeriodInSeconds(config.UpdateFrequencyInSeconds)\n                .SetApplicationRestartCount(config.ApplicationRestartCount)\n                .Build();\n            _yamsService = YamsServiceFactory.Create(yamsConfig,\n                deploymentRepositoryStorageConnectionString: config.StorageDataConnectionString,\n                updateSessionStorageConnectionString: config.StorageDataConnectionString);\n\n            try\n            {\n                Trace.TraceInformation(\"Yams is starting\");\n                await _yamsService.Start();\n                Trace.TraceInformation(\"Yams has started. Looking for apps with deploymentId:\" + yamsConfig.ClusterDeploymentId);\n                while (true)\n                {\n                    await Task.Delay(1000);\n                }\n            }\n            catch (Exception ex)\n            {\n                Trace.TraceError(ex.ToString());\n            }\n        }\n\n        public override bool OnStart()\n        {\n            Trace.TraceInformation(\"Yams WorkerRole is starting\");\n            ServicePointManager.DefaultConnectionLimit = 1000;\n            RoleEnvironment.Changing += RoleEnvironmentChanging;\n            var result = base.OnStart();\n            Trace.TraceInformation(\"Yams WorkerRole has started\");\n            return result;\n        }\n\n        public override void OnStop()\n        {\n            StopAsync().Wait();\n        }\n\n        public async Task StopAsync()\n        {\n            Trace.TraceInformation(\"Yams WorkerRole is stopping\");\n            RoleEnvironment.Changing -= RoleEnvironmentChanging;\n            if (_yamsService != null)\n            {\n                await _yamsService.Stop();\n            }\n            base.OnStop();\n            Trace.TraceInformation(\"Yams has stopped\");\n        }\n\n        private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)\n        {\n            // If a configuration setting is changing);\n            if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))\n            {\n                e.Cancel = true;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.WorkerRole/WorkerRoleConfig.cs",
    "content": "using System;\nusing Microsoft.WindowsAzure.ServiceRuntime;\n\nnamespace Etg.Yams.WorkerRole\n{\n    public class WorkerRoleConfig\n    {\n        public WorkerRoleConfig()\n        {\n            UpdateFrequencyInSeconds = Convert.ToInt32(RoleEnvironment.GetConfigurationSettingValue(\"UpdateFrequencyInSeconds\"));\n            ApplicationRestartCount = Convert.ToInt32(RoleEnvironment.GetConfigurationSettingValue(\"ApplicationRestartCount\"));\n            StorageDataConnectionString = RoleEnvironment.GetConfigurationSettingValue(\"StorageDataConnectionString\");\n            CurrentRoleInstanceLocalStoreDirectory = RoleEnvironment.GetLocalResource(\"LocalStoreDirectory\").RootPath;\n        }\n\n        public string StorageDataConnectionString { get; }\n\n        public string CurrentRoleInstanceLocalStoreDirectory { get; }\n\n        public int UpdateFrequencyInSeconds { get; }\n\n        public int ApplicationRestartCount { get; }\n    }\n}"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.WorkerRole/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <system.diagnostics>\n    <trace>\n      <listeners>\n        <add type=\"Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\" name=\"AzureDiagnostics\">\n          <filter type=\"\" />\n        </add>\n      </listeners>\n    </trace>\n  </system.diagnostics>  \n  <runtime>\n    <gcServer enabled=\"true\"></gcServer>\n    <gcConcurrent enabled=\"false\"></gcConcurrent>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"MonAgentListener\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-1.0.0.0\" newVersion=\"1.0.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.WindowsAzure.Storage\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-7.0.0.0\" newVersion=\"7.0.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" /></startup></configuration>\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Etg.Yams.WorkerRole/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net451\" />\n  <package id=\"EnterpriseLibrary.TransientFaultHandling\" version=\"6.0.1304.0\" targetFramework=\"net451\" />\n  <package id=\"Etg.Yams\" version=\"1.0.14\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.AspNet.Cors\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.Client\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.Core\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.Owin\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.OwinSelfHost\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Owin\" version=\"3.0.1\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Owin.Cors\" version=\"3.0.1\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Owin.Host.HttpListener\" version=\"3.0.1\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Owin.Hosting\" version=\"3.0.1\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Owin.Security\" version=\"3.0.1\" targetFramework=\"net45\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"Owin\" version=\"1.0\" targetFramework=\"net45\" />\n  <package id=\"Rx-Core\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"Rx-Interfaces\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"Rx-Linq\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"Rx-Main\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"Rx-PlatformServices\" version=\"2.2.5\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"7.0.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Frontend/Frontend.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProductVersion>8.0.30703</ProductVersion>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>{C80821C2-215C-429E-A6A3-BFB132B5C1F4}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Frontend</RootNamespace>\n    <AssemblyName>Frontend</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <RoleType>Worker</RoleType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Edm.5.6.4\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.OData.5.6.4\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Services.Client.5.6.4\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Diagnostics, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\">\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.ServiceRuntime, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\">\n      <Private>False</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\WindowsAzure.Storage.7.0.0\\lib\\net40\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Spatial.5.6.4\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"WorkerRole.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\">\n      <SubType>Designer</SubType>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Etg.Yams.WorkerRole\\Etg.Yams.WorkerRole.csproj\">\n      <Project>{b38d7d2a-bdc1-49fe-b0dd-d799e3e746ad}</Project>\n      <Name>Etg.Yams.WorkerRole</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n  <PropertyGroup>\n    <!-- Setting AutoUnifyAssemblyReferences to false will allow the ResolveAssemblyReferences task to \n    create warnings when detecting version missmatches among references.\n    -->\n    <AutoUnifyAssemblyReferences>false</AutoUnifyAssemblyReferences>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Frontend/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Frontend\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Frontend\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"c80821c2-215c-429e-a6a3-bfb132b5c1f4\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Frontend/WorkerRole.cs",
    "content": "using Etg.Yams.WorkerRole;\n\nnamespace Frontend\n{\n    public class WorkerRole : YamsWorkerRole\n    {\n        protected override bool IsSingleClusterDeployment\n        {\n            get { return false; }\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Frontend/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <system.diagnostics>\n    <trace>\n      <listeners>\n        <add type=\"Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\" name=\"AzureDiagnostics\">\n          <filter type=\"\" />\n        </add>\n      </listeners>\n    </trace>\n  </system.diagnostics>  \n  <runtime>\n    <gcServer enabled=\"true\"></gcServer>\n    <gcConcurrent enabled=\"false\"></gcConcurrent>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"MonAgentListener\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-1.0.0.0\" newVersion=\"1.0.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.WindowsAzure.Storage\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-7.0.0.0\" newVersion=\"7.0.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" /></startup></configuration>\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/Frontend/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"7.0.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/SingleClusterRole/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"SingleClusterRole\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"SingleClusterRole\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"d6eb9dd4-4dc6-4cf1-888b-4a4a548e3fd1\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/SingleClusterRole/SingleClusterRole.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProductVersion>8.0.30703</ProductVersion>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>{D6EB9DD4-4DC6-4CF1-888B-4A4A548E3FD1}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>SingleClusterRole</RootNamespace>\n    <AssemblyName>SingleClusterRole</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <RoleType>Worker</RoleType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Edm.5.6.4\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.OData.5.6.4\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Services.Client.5.6.4\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Diagnostics, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\">\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.ServiceRuntime, Version=2.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\">\n      <Private>False</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\WindowsAzure.Storage.7.0.0\\lib\\net40\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Spatial.5.6.4\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"WorkerRole.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\">\n      <SubType>Designer</SubType>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Etg.Yams.WorkerRole\\Etg.Yams.WorkerRole.csproj\">\n      <Project>{b38d7d2a-bdc1-49fe-b0dd-d799e3e746ad}</Project>\n      <Name>Etg.Yams.WorkerRole</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n  <PropertyGroup>\n    <!-- Setting AutoUnifyAssemblyReferences to false will allow the ResolveAssemblyReferences task to \n    create warnings when detecting version missmatches among references.\n    -->\n    <AutoUnifyAssemblyReferences>false</AutoUnifyAssemblyReferences>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/SingleClusterRole/WorkerRole.cs",
    "content": "using Etg.Yams.WorkerRole;\n\nnamespace SingleClusterRole\n{\n    public class WorkerRole : YamsWorkerRole\n    {\n        protected override bool IsSingleClusterDeployment\n        {\n            get { return true; }\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/SingleClusterRole/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <system.diagnostics>\n    <trace>\n      <listeners>\n        <add type=\"Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=2.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\" name=\"AzureDiagnostics\">\n          <filter type=\"\" />\n        </add>\n      </listeners>\n    </trace>\n  </system.diagnostics>  \n  <runtime>\n    <gcServer enabled=\"true\"></gcServer>\n    <gcConcurrent enabled=\"false\"></gcConcurrent>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"MonAgentListener\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-1.0.0.0\" newVersion=\"1.0.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.WindowsAzure.Storage\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-7.0.0.0\" newVersion=\"7.0.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" /></startup></configuration>\n"
  },
  {
    "path": "Samples/Etg.Yams.Cloud/SingleClusterRole/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"7.0.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "Samples/OrleansApp/GrainInterfaces/GrainInterfaces.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProductVersion>8.0.30703</ProductVersion>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>{E2AD22B1-8ADD-4547-9013-F99269E45D76}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>GrainInterfaces</RootNamespace>\n    <AssemblyName>GrainInterfaces</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n    <NuGetPackageImportStamp>\n    </NuGetPackageImportStamp>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.7.0.1\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Orleans, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.Core.1.2.3\\lib\\net451\\Orleans.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"IHelloGrain.cs\" />\n    <Compile Include=\"Properties\\orleans.codegen.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <Import Project=\"..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.Build.1.2.3\\build\\Microsoft.Orleans.OrleansCodeGenerator.Build.targets\" Condition=\"Exists('..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.Build.1.2.3\\build\\Microsoft.Orleans.OrleansCodeGenerator.Build.targets')\" />\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.Build.1.2.3\\build\\Microsoft.Orleans.OrleansCodeGenerator.Build.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.Build.1.2.3\\build\\Microsoft.Orleans.OrleansCodeGenerator.Build.targets'))\" />\n  </Target>\n</Project>"
  },
  {
    "path": "Samples/OrleansApp/GrainInterfaces/IHelloGrain.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Orleans;\n\nnamespace GrainInterfaces\n{\n    /// <summary>\n    /// Grain interface IGrain1\n    /// </summary>\n    public interface IHelloGrain : IGrainWithIntegerKey\n    {\n        Task<string> SayHello();\n    }\n}\n"
  },
  {
    "path": "Samples/OrleansApp/GrainInterfaces/Properties/AssemblyInfo.cs",
    "content": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"GrainInterfaces\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"GrainInterfaces\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2015\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"c5b7c5cf-fd0d-40d1-86e0-3583c7b20e36\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/OrleansApp/GrainInterfaces/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Orleans.Core\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Orleans.OrleansCodeGenerator.Build\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"7.0.1\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "Samples/OrleansApp/Grains/Grains.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProductVersion>8.0.30703</ProductVersion>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>{CA198D37-D8DC-4099-ACB8-AA9396C6DEB3}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Grains</RootNamespace>\n    <AssemblyName>Grains</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n    <NuGetPackageImportStamp>\n    </NuGetPackageImportStamp>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(OrleansSDK)' != '' \">\n    <StartAction>Program</StartAction>\n    <StartProgram>$(OrleansSDK)\\LocalSilo\\OrleansHost.exe</StartProgram>\n    <StartWorkingDirectory>$(OrleansSDK)\\LocalSilo</StartWorkingDirectory>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.7.0.1\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Orleans, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.Core.1.2.3\\lib\\net451\\Orleans.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"HelloGrain.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Properties\\orleans.codegen.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\GrainInterfaces\\GrainInterfaces.csproj\">\n      <Project>{e2ad22b1-8add-4547-9013-f99269e45d76}</Project>\n      <Name>GrainInterfaces</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <PropertyGroup>\n    <PostBuildEvent>\n      if exist \"$(OrleansSDK)\\LocalSilo\" (\n      if not exist \"$(OrleansSDK)\\LocalSilo\\Applications\" (md \"$(OrleansSDK)\\LocalSilo\\Applications\")\n      if not exist  \"$(OrleansSDK)\\LocalSilo\\Applications\\$(RootNamespace)\" (md \"$(OrleansSDK)\\LocalSilo\\Applications\\$(RootNamespace)\")\n      copy /y *.dll  \"$(OrleansSDK)\\LocalSilo\\Applications\\$(RootNamespace)\\\"\n      copy /y *.pdb  \"$(OrleansSDK)\\LocalSilo\\Applications\\$(RootNamespace)\\\"\n      )\n    </PostBuildEvent>\n  </PropertyGroup>\n  <Import Project=\"..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.Build.1.2.3\\build\\Microsoft.Orleans.OrleansCodeGenerator.Build.targets\" Condition=\"Exists('..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.Build.1.2.3\\build\\Microsoft.Orleans.OrleansCodeGenerator.Build.targets')\" />\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.Build.1.2.3\\build\\Microsoft.Orleans.OrleansCodeGenerator.Build.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.Build.1.2.3\\build\\Microsoft.Orleans.OrleansCodeGenerator.Build.targets'))\" />\n  </Target>\n</Project>"
  },
  {
    "path": "Samples/OrleansApp/Grains/HelloGrain.cs",
    "content": "﻿using System.Threading.Tasks;\nusing GrainInterfaces;\nusing Orleans;\n\nnamespace Grains\n{\n    /// <summary>\n    /// Grain implementation class Grain1.\n    /// </summary>\n    public class HelloGrain : Grain, IHelloGrain\n    {\n        public Task<string> SayHello()\n        {\n            return Task.FromResult(\"Hello World!\");\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/OrleansApp/Grains/Properties/AssemblyInfo.cs",
    "content": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Grains\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Grains\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2015\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"4743e305-a455-4c87-9686-f9494f38ba7c\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/OrleansApp/Grains/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Orleans.Core\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Orleans.OrleansCodeGenerator.Build\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"7.0.1\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "Samples/OrleansApp/OrleansApp.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.25123.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"GrainInterfaces\", \"GrainInterfaces\\GrainInterfaces.csproj\", \"{E2AD22B1-8ADD-4547-9013-F99269E45D76}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Grains\", \"Grains\\Grains.csproj\", \"{CA198D37-D8DC-4099-ACB8-AA9396C6DEB3}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"WebApp\", \"WebApp\\WebApp.csproj\", \"{B93B7872-46CC-4386-B7A0-C6068A4A2659}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"SiloHost\", \"SiloHost\\SiloHost.csproj\", \"{14A06759-E06D-4755-8D22-BC7D09791DC1}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{E2AD22B1-8ADD-4547-9013-F99269E45D76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E2AD22B1-8ADD-4547-9013-F99269E45D76}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E2AD22B1-8ADD-4547-9013-F99269E45D76}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E2AD22B1-8ADD-4547-9013-F99269E45D76}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{CA198D37-D8DC-4099-ACB8-AA9396C6DEB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{CA198D37-D8DC-4099-ACB8-AA9396C6DEB3}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{CA198D37-D8DC-4099-ACB8-AA9396C6DEB3}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{CA198D37-D8DC-4099-ACB8-AA9396C6DEB3}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{B93B7872-46CC-4386-B7A0-C6068A4A2659}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B93B7872-46CC-4386-B7A0-C6068A4A2659}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B93B7872-46CC-4386-B7A0-C6068A4A2659}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B93B7872-46CC-4386-B7A0-C6068A4A2659}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{14A06759-E06D-4755-8D22-BC7D09791DC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{14A06759-E06D-4755-8D22-BC7D09791DC1}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{14A06759-E06D-4755-8D22-BC7D09791DC1}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{14A06759-E06D-4755-8D22-BC7D09791DC1}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Samples/OrleansApp/SiloHost/App.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <gcServer enabled=\"true\"/>\n    <gcConcurrent enabled=\"false\"/>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Newtonsoft.Json\" publicKeyToken=\"30ad4fe6b2a6aeed\" culture=\"neutral\"/>\n        <bindingRedirect oldVersion=\"0.0.0.0-7.0.0.0\" newVersion=\"7.0.0.0\"/>\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n  <startup>\n    <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\"/>\n  </startup>\n</configuration>\n"
  },
  {
    "path": "Samples/OrleansApp/SiloHost/AppConfig.json",
    "content": "﻿{\n  \"ExeName\": \"SiloHost.exe\",\n  \"ExeArgs\": \"deploymentid=${Id}_${Version.Major}.${Version.Minor}_${DeploymentId}\"\n}\n"
  },
  {
    "path": "Samples/OrleansApp/SiloHost/OrleansHostWrapper.cs",
    "content": "using System;\nusing System.Net;\nusing System.Reflection;\nusing Orleans.Runtime.Configuration;\nusing Orleans.Runtime;\n\nnamespace SiloHost\n{\n    class OrleansHostWrapper\n    {\n        private readonly Orleans.Runtime.Host.SiloHost siloHost;\n\n        public OrleansHostWrapper(ClusterConfiguration config, string[] args)\n        {\n            var siloArgs = SiloArgs.ParseArguments(args);\n            if (siloArgs == null)\n            {\n                return;\n            }\n\n            if (siloArgs.DeploymentId != null)\n            {\n                config.Globals.DeploymentId = siloArgs.DeploymentId;\n            }\n\n            siloHost = new Orleans.Runtime.Host.SiloHost(siloArgs.SiloName, config);\n            siloHost.LoadOrleansConfig();\n        }\n\n        public int Run()\n        {\n            if (siloHost == null)\n            {\n                SiloArgs.PrintUsage();\n                return 1;\n            }\n\n            try\n            {\n                siloHost.InitializeOrleansSilo();\n\n                if (siloHost.StartOrleansSilo())\n                {\n                    Console.WriteLine($\"Successfully started Orleans silo '{siloHost.Name}' as a {siloHost.Type} node.\");\n                    return 0;\n                }\n                else\n                {\n                    throw new OrleansException($\"Failed to start Orleans silo '{siloHost.Name}' as a {siloHost.Type} node.\");\n                }\n            }\n            catch (Exception exc)\n            {\n                siloHost.ReportStartupError(exc);\n                Console.Error.WriteLine(exc);\n                return 1;\n            }\n        }\n\n\n        public int Stop()\n        {\n            if (siloHost != null)\n            {\n                try\n                {\n                    siloHost.StopOrleansSilo();\n                    siloHost.Dispose();\n                    Console.WriteLine($\"Orleans silo '{siloHost.Name}' shutdown.\");\n                }\n                catch (Exception exc)\n                {\n                    siloHost.ReportStartupError(exc);\n                    Console.Error.WriteLine(exc);\n                    return 1;\n                }\n            }\n            return 0;\n        }\n\n        private class SiloArgs\n        {\n            public SiloArgs(string siloName, string deploymentId)\n            {\n                this.DeploymentId = deploymentId;\n                this.SiloName = siloName;\n            }\n\n            public static SiloArgs ParseArguments(string[] args)\n            {\n                string deploymentId = null;\n                string siloName = null;\n\n                for (int i = 0; i < args.Length; i++)\n                {\n                    string arg = args[i];\n                    if (arg.StartsWith(\"-\") || arg.StartsWith(\"/\"))\n                    {\n                        switch (arg.ToLowerInvariant())\n                        {\n                            case \"/?\":\n                            case \"/help\":\n                            case \"-?\":\n                            case \"-help\":\n                                // Query usage help. Return null so that usage is printed.\n                                return null;\n                            default:\n                                Console.WriteLine($\"Bad command line arguments supplied: {arg}\");\n                                return null;\n                        }\n                    }\n                    else if (arg.Contains(\"=\"))\n                    {\n                        string[] parameters = arg.Split('=');\n                        if (String.IsNullOrEmpty(parameters[1]))\n                        {\n                            Console.WriteLine($\"Bad command line arguments supplied: {arg}\");\n                            return null;\n                        }\n                        switch (parameters[0].ToLowerInvariant())\n                        {\n                            case \"deploymentid\":\n                                deploymentId = parameters[1];\n                                break;\n                            case \"name\":\n                                siloName = parameters[1];\n                                break;\n                            default:\n                                Console.WriteLine($\"Bad command line arguments supplied: {arg}\");\n                                return null;\n                        }\n                    }\n                    else\n                    {\n                        Console.WriteLine($\"Bad command line arguments supplied: {arg}\");\n                        return null;\n                    }\n                }\n\n                // Default to machine name\n                siloName = siloName ?? Dns.GetHostName();\n                return new SiloArgs(siloName, deploymentId);\n            }\n\n            public static void PrintUsage()\n            {\n                string consoleAppName = Assembly.GetExecutingAssembly().GetName().Name;\n                Console.WriteLine(\n                    $@\"USAGE: {consoleAppName} [name=<siloName>] [deploymentId=<idString>] [/debug]\n                Where:\n                name=<siloName> - Name of this silo (optional)\n                deploymentId=<idString> - Optionally override the deployment group this host instance should run in \n                (otherwise will use the one in the configuration\");\n            }\n\n            public string SiloName { get; set; }\n            public string DeploymentId { get; set; }\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/OrleansApp/SiloHost/Program.cs",
    "content": "using System;\nusing System.Net;\nusing Orleans.Runtime;\nusing Orleans.Runtime.Configuration;\n\nnamespace SiloHost\n{\n    /// <summary>\n    /// Orleans test silo host\n    /// </summary>\n    public class Program\n    {\n        private static OrleansHostWrapper hostWrapper;\n        static int Main(string[] args)\n        {\n            int exitCode = StartSilo(args);\n\n            Console.WriteLine(\"Orleans Silo is running.\\nPress Enter to terminate...\");\n            Console.ReadLine();\n\n            exitCode += ShutdownSilo();\n\n            //either StartSilo or ShutdownSilo failed would result on a non-zero exit code. \n            return exitCode;\n        }\n\n        private static int StartSilo(string[] args)\n        {\n            // define the cluster configuration\n            var config = new ClusterConfiguration();\n            config.Globals.LivenessType = GlobalConfiguration.LivenessProviderType.AzureTable;\n            config.Globals.ReminderServiceType = GlobalConfiguration.ReminderServiceProviderType.AzureTable;\n            config.Globals.DataConnectionString = \"MY_DATA_CONNECTION_STRING\";\n            config.AddMemoryStorageProvider();\n            config.AddAzureTableStorageProvider(\"AzureStore\");\n            config.Defaults.DefaultTraceLevel = Severity.Error;\n            config.Defaults.Port = 100;\n            config.Defaults.ProxyGatewayEndpoint = new IPEndPoint(config.Defaults.Endpoint.Address, 101);\n\n            hostWrapper = new OrleansHostWrapper(config, args);\n            return hostWrapper.Run();\n        }\n\n        private static int ShutdownSilo()\n        {\n            if (hostWrapper != null)\n            {\n                return hostWrapper.Stop();\n            }\n            return 0;\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/OrleansApp/SiloHost/Properties/AssemblyInfo.cs",
    "content": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"SiloHost\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"SiloHost\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"7a0380bb-f9d6-4800-a450-db76c6fdb41a\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/OrleansApp/SiloHost/SiloHost.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform>AnyCPU</Platform>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>{14A06759-E06D-4755-8D22-BC7D09791DC1}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>SiloHost</RootNamespace>\n    <AssemblyName>SiloHost</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.CodeAnalysis, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.CodeAnalysis.Common.1.0.0\\lib\\net45\\Microsoft.CodeAnalysis.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.CodeAnalysis.CSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.CodeAnalysis.CSharp.1.0.0\\lib\\net45\\Microsoft.CodeAnalysis.CSharp.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Edm.5.6.4\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.OData.5.6.4\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Services.Client.5.6.4\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=5.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\WindowsAzure.Storage.5.0.2\\lib\\net40\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.7.0.1\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Orleans, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.Core.1.2.3\\lib\\net451\\Orleans.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansAzureUtils, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansAzureUtils.1.2.3\\lib\\net451\\OrleansAzureUtils.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansCodeGenerator, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.1.2.3\\lib\\net451\\OrleansCodeGenerator.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansCounterControl, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.CounterControl.1.2.3\\lib\\net451\\OrleansCounterControl.exe</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansDependencyInjection, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansRuntime.1.2.3\\lib\\net451\\OrleansDependencyInjection.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansHost, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansHost.1.2.3\\lib\\net451\\OrleansHost.exe</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansProviders, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansProviders.1.2.3\\lib\\net451\\OrleansProviders.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansRuntime, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansRuntime.1.2.3\\lib\\net451\\OrleansRuntime.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Collections.Immutable, Version=1.1.36.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Collections.Immutable.1.1.36\\lib\\portable-net45+win8+wp8+wpa81\\System.Collections.Immutable.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"System.Reflection.Metadata, Version=1.0.21.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Reflection.Metadata.1.0.21\\lib\\portable-net45+win8\\System.Reflection.Metadata.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Spatial.5.6.4\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Xml\" />\n    <Reference Include=\"System.Xml.Linq\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"OrleansHostWrapper.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Include=\"AppConfig.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Analyzer Include=\"..\\packages\\Microsoft.CodeAnalysis.Analyzers.1.0.0\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.Analyzers.dll\" />\n    <Analyzer Include=\"..\\packages\\Microsoft.CodeAnalysis.Analyzers.1.0.0\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.CSharp.Analyzers.dll\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\GrainInterfaces\\GrainInterfaces.csproj\">\n      <Project>{2e3fa094-c7b7-4698-a032-5bef7bfec73b}</Project>\n      <Name>GrainInterfaces1</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Grains\\Grains.csproj\">\n      <Project>{8e9744e5-0691-4752-ba9e-56d57d024a33}</Project>\n      <Name>Grains1</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "Samples/OrleansApp/SiloHost/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.CodeAnalysis.Analyzers\" version=\"1.0.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.CodeAnalysis.Common\" version=\"1.0.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.CodeAnalysis.CSharp\" version=\"1.0.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.6.4\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.6.4\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.6.4\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Orleans.Core\" version=\"1.2.3\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Orleans.CounterControl\" version=\"1.2.3\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Orleans.OrleansAzureUtils\" version=\"1.2.3\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Orleans.OrleansCodeGenerator\" version=\"1.2.3\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Orleans.OrleansHost\" version=\"1.2.3\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Orleans.OrleansProviders\" version=\"1.2.3\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Orleans.OrleansRuntime\" version=\"1.2.3\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Orleans.Server\" version=\"1.2.3\" targetFramework=\"net452\" />\n  <package id=\"Newtonsoft.Json\" version=\"7.0.1\" targetFramework=\"net452\" />\n  <package id=\"System.Collections.Immutable\" version=\"1.1.36\" targetFramework=\"net452\" />\n  <package id=\"System.Reflection.Metadata\" version=\"1.0.21\" targetFramework=\"net452\" />\n  <package id=\"System.Spatial\" version=\"5.6.4\" targetFramework=\"net452\" />\n  <package id=\"WindowsAzure.Storage\" version=\"5.0.2\" targetFramework=\"net452\" />\n</packages>"
  },
  {
    "path": "Samples/OrleansApp/WebApp/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" />\n    </startup>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Newtonsoft.Json\" publicKeyToken=\"30ad4fe6b2a6aeed\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-7.0.0.0\" newVersion=\"7.0.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>\n"
  },
  {
    "path": "Samples/OrleansApp/WebApp/App.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Sockets;\nusing System.Threading;\nusing Orleans;\nusing Orleans.Runtime;\nusing Orleans.Runtime.Configuration;\n\nnamespace WebApp\n{\n    public class App\n    {\n        public static string Id;\n        public static string Version;\n        public static string DeploymentId;\n\n        static void Main(string[] args)\n        {\n            Id = args[0];\n            Version = args[1];\n            DeploymentId = args[2];\n\n            Version version = new Version(Version);\n            string apiVersion = string.Format(\"{0}.{1}\", version.Major, version.Minor);\n            string baseUrl = string.Format(\"http://{0}/{1}/{2}\", GetIpAddress(), Id, apiVersion);\n            Console.WriteLine(\"Url is: \" + baseUrl);\n\n            // Start OWIN host \n            Microsoft.Owin.Hosting.WebApp.Start<Startup>(url: baseUrl);\n            Console.WriteLine(\"WebApp has been started successfully\");\n\n            var config = new ClientConfiguration();\n            config.GatewayProvider = ClientConfiguration.GatewayProviderType.AzureTable;\n            config.DeploymentId = \"hello.orleans_1.0_MY_YAMS_BACKEND_CLUSTER_ID\";\n            config.DataConnectionString = \"MY_DATA_CONNECTION_STRING\";\n            config.DefaultTraceLevel = Severity.Error;\n\n            // Attempt to connect a few times to overcome transient failures and to give the silo enough \n            // time to start up when starting at the same time as the client (useful when deploying or during development).\n\n            const int initializeAttemptsBeforeFailing = 5;\n\n            int attempt = 0;\n            while (true)\n            {\n                try\n                {\n                    GrainClient.Initialize(config);\n                    Console.WriteLine(\"Client initialized\");\n                    break;\n                }\n                catch (SiloUnavailableException e)\n                {\n                    attempt++;\n                    if (attempt >= initializeAttemptsBeforeFailing)\n                    {\n                        throw;\n                    }\n                    Thread.Sleep(TimeSpan.FromSeconds(2));\n                }\n            }\n\n            Console.ReadLine(); \n\n        }\n\n        private static string GetIpAddress()\n        {\n            var host = Dns.GetHostEntry(Dns.GetHostName());\n            return host.AddressList.First(x => x.AddressFamily == AddressFamily.InterNetwork).ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/OrleansApp/WebApp/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"WebApp.exe\",\n    \"ExeArgs\": \"${Id} ${Version} ${DeploymentId}\"\n}\n"
  },
  {
    "path": "Samples/OrleansApp/WebApp/ApplicationController.cs",
    "content": "﻿using System.Threading.Tasks;\nusing System.Web.Http;\nusing Newtonsoft.Json.Linq;\n\nnamespace WebApp\n{\n    [RoutePrefix(\"application\")]\n    public class ApplicationController : ApiController\n    {\n        [Route(\"info\")]\n        public JObject GetInfo()\n        {\n            string json = string.Format(@\"\n                {{\n                    'Id': '{0}',\n                    'Version': '{1}',\n                    'Cloud Service Deployment Id': '{2}'\n                }}\n                \", App.Id, App.Version, App.DeploymentId);\n\n            return JObject.Parse(json);\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/OrleansApp/WebApp/OrleansHelloController.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing System.Web.Http;\nusing GrainInterfaces;\nusing Orleans;\n\nnamespace WebApp\n{\n    [RoutePrefix(\"orleans\")]\n    public class OrleansHelloController : ApiController\n    {\n        [HttpGet]\n        [Route(\"hello\")]\n        public async Task<string> SayHello()\n        {\n            var helloGrain = GrainClient.GrainFactory.GetGrain<IHelloGrain>(0);\n            return await helloGrain.SayHello();\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/OrleansApp/WebApp/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"WebApp\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"WebApp\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2015\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"e09bbf9f-7e9d-4635-93b8-1d491adb8b90\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/OrleansApp/WebApp/Startup.cs",
    "content": "﻿using System;\nusing System.Web.Http;\nusing Owin;\n\nnamespace WebApp\n{\n    class Startup\n    {\n        // This code configures Web API. The Startup class is specified as a type\n        // parameter in the WebApp.Start method.\n        public void Configuration(IAppBuilder appBuilder)\n        {\n            // Configure Web API for self-host. \n            HttpConfiguration config = new HttpConfiguration();\n            config.MapHttpAttributeRoutes();\n            config.Routes.MapHttpRoute(\n                name: \"DefaultApi\",\n                routeTemplate: \"api/{controller}/{id}\",\n                defaults: new { id = RouteParameter.Optional }\n            );\n            config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;\n            config.EnsureInitialized();\n            appBuilder.UseWebApi(config);\n\n            Console.WriteLine(\"Available Apis:\");\n            foreach (var api in config.Services.GetApiExplorer().ApiDescriptions)\n            {\n                Console.WriteLine(\"{0} {1}\", api.HttpMethod, api.RelativePath);\n            }\n        } \n    }\n}\n"
  },
  {
    "path": "Samples/OrleansApp/WebApp/WebApp.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{B93B7872-46CC-4386-B7A0-C6068A4A2659}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>WebApp</RootNamespace>\n    <AssemblyName>WebApp</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.CodeAnalysis, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.CodeAnalysis.Common.1.0.0\\lib\\net45\\Microsoft.CodeAnalysis.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.CodeAnalysis.CSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.CodeAnalysis.CSharp.1.0.0\\lib\\net45\\Microsoft.CodeAnalysis.CSharp.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Edm.5.6.4\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.OData.5.6.4\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Services.Client.5.6.4\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Owin.2.0.2\\lib\\net45\\Microsoft.Owin.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Owin.Host.HttpListener, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Owin.Host.HttpListener.2.0.2\\lib\\net45\\Microsoft.Owin.Host.HttpListener.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Owin.Hosting, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Owin.Hosting.2.0.2\\lib\\net45\\Microsoft.Owin.Hosting.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.WindowsAzure.ConfigurationManager.2.0.0.0\\lib\\net40\\Microsoft.WindowsAzure.Configuration.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=5.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\WindowsAzure.Storage.5.0.2\\lib\\net40\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.7.0.1\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Orleans, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.Core.1.2.3\\lib\\net451\\Orleans.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansAzureUtils, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansAzureUtils.1.2.3\\lib\\net451\\OrleansAzureUtils.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansCodeGenerator, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansCodeGenerator.1.2.3\\lib\\net451\\OrleansCodeGenerator.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansDependencyInjection, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansRuntime.1.2.3\\lib\\net451\\OrleansDependencyInjection.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansProviders, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansProviders.1.2.3\\lib\\net451\\OrleansProviders.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"OrleansRuntime, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Orleans.OrleansRuntime.1.2.3\\lib\\net451\\OrleansRuntime.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Owin.1.0\\lib\\net40\\Owin.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Collections.Immutable, Version=1.1.36.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Collections.Immutable.1.1.36\\lib\\portable-net45+win8+wp8+wpa81\\System.Collections.Immutable.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.AspNet.WebApi.Client.5.2.3\\lib\\net45\\System.Net.Http.Formatting.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reflection.Metadata, Version=1.0.21.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Reflection.Metadata.1.0.21\\lib\\portable-net45+win8\\System.Reflection.Metadata.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\System.Spatial.5.6.4\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.AspNet.WebApi.Core.5.2.3\\lib\\net45\\System.Web.Http.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.AspNet.WebApi.Owin.5.2.3\\lib\\net45\\System.Web.Http.Owin.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"App.cs\" />\n    <Compile Include=\"OrleansHelloController.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"ApplicationController.cs\" />\n    <Compile Include=\"Startup.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Include=\"AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\GrainInterfaces\\GrainInterfaces.csproj\">\n      <Project>{e2ad22b1-8add-4547-9013-f99269e45d76}</Project>\n      <Name>GrainInterfaces</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <Analyzer Include=\"..\\packages\\Microsoft.CodeAnalysis.Analyzers.1.0.0\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.Analyzers.dll\" />\n    <Analyzer Include=\"..\\packages\\Microsoft.CodeAnalysis.Analyzers.1.0.0\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.CSharp.Analyzers.dll\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "Samples/OrleansApp/WebApp/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.AspNet.WebApi.Client\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.Core\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.Owin\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.OwinSelfHost\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.CodeAnalysis.Analyzers\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.CodeAnalysis.Common\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.CodeAnalysis.CSharp\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Orleans.Client\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Orleans.Core\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Orleans.OrleansAzureUtils\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Orleans.OrleansCodeGenerator\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Orleans.OrleansProviders\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Orleans.OrleansRuntime\" version=\"1.2.3\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Owin\" version=\"2.0.2\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Owin.Host.HttpListener\" version=\"2.0.2\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Owin.Hosting\" version=\"2.0.2\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.WindowsAzure.ConfigurationManager\" version=\"2.0.0.0\" targetFramework=\"net45\" />\n  <package id=\"Newtonsoft.Json\" version=\"7.0.1\" targetFramework=\"net451\" />\n  <package id=\"Owin\" version=\"1.0\" targetFramework=\"net45\" />\n  <package id=\"System.Collections.Immutable\" version=\"1.1.36\" targetFramework=\"net451\" />\n  <package id=\"System.Reflection.Metadata\" version=\"1.0.21\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.6.4\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"5.0.2\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "Samples/Samples.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.24720.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"YamsStudio\", \"YamsStudio\\YamsStudio.csproj\", \"{41BD41B6-362E-4924-B801-7C2138A55BFF}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{41BD41B6-362E-4924-B801-7C2138A55BFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{41BD41B6-362E-4924-B801-7C2138A55BFF}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{41BD41B6-362E-4924-B801-7C2138A55BFF}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{41BD41B6-362E-4924-B801-7C2138A55BFF}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tEnterpriseLibraryConfigurationToolBinariesPathV6 = packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Samples/WebApp/PublishScripts/AzureWebsitePublishModule.psm1",
    "content": "﻿#  AzureWebSitePublishModule.psm1 is a Windows PowerShell script module. This module exports Windows PowerShell functions that automate life cycle management for web applications. You can use the functions as is or customize them for your application and publishing environment.\n\nSet-StrictMode -Version 3\n\n# A variable to save original subscription.\n$Script:originalCurrentSubscription = $null\n\n# A variable to save original storage account.\n$Script:originalCurrentStorageAccount = $null\n\n# A variable to save storage account of user specified subscription.\n$Script:originalStorageAccountOfUserSpecifiedSubscription = $null\n\n# A variable to save subscription name.\n$Script:userSpecifiedSubscription = $null\n\n\n<#\n.SYNOPSIS\nPrepends the date and time to a message.\n\n.DESCRIPTION\nPrepends the date and time to a message. This function is designed for messages written to the Error and Verbose streams.\n\n.PARAMETER  Message\nSpecifies the messages without the date.\n\n.INPUTS\nSystem.String\n\n.OUTPUTS\nSystem.String\n\n.EXAMPLE\nPS C:\\> Format-DevTestMessageWithTime -Message \"Adding file $filename to the directory\"\n2/5/2014 1:03:08 PM - Adding file $filename to the directory\n\n.LINK\nWrite-VerboseWithTime\n\n.LINK\nWrite-ErrorWithTime\n#>\nfunction Format-DevTestMessageWithTime\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Position=0, Mandatory = $true, ValueFromPipeline = $true)]\n        [String]\n        $Message\n    )\n\n    return ((Get-Date -Format G)  + ' - ' + $Message)\n}\n\n\n<#\n\n.SYNOPSIS\nWrites an error message prefixed with the current time.\n\n.DESCRIPTION\nWrites an error message prefixed with the current time. This function calls the Format-DevTestMessageWithTime function to prepend the time before writing the message to the Error stream.\n\n.PARAMETER  Message\nSpecifies the message in the error message call. You can pipe the message string to the function.\n\n.INPUTS\nSystem.String\n\n.OUTPUTS\nNone. The function writes to the Error stream.\n\n.EXAMPLE\nPS C:> Write-ErrorWithTime -Message \"Failed. Cannot find the file.\"\n\nWrite-Error: 2/6/2014 8:37:29 AM - Failed. Cannot find the file.\n + CategoryInfo     : NotSpecified: (:) [Write-Error], WriteErrorException\n + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException\n\n.LINK\nWrite-Error\n\n#>\nfunction Write-ErrorWithTime\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Position=0, Mandatory = $true, ValueFromPipeline = $true)]\n        [String]\n        $Message\n    )\n\n    $Message | Format-DevTestMessageWithTime | Write-Error\n}\n\n\n<#\n.SYNOPSIS\nWrites a verbose message prefixed with the current time.\n\n.DESCRIPTION\nWrites a verbose message prefixed with the current time. Because it calls Write-Verbose, the message displays only when the script runs with the Verbose parameter or when the VerbosePreference preference is set to Continue.\n\n.PARAMETER  Message\nSpecifies the message in the verbose message call. You can pipe the message string to the function.\n\n.INPUTS\nSystem.String\n\n.OUTPUTS\nNone. The function writes to the Verbose stream.\n\n.EXAMPLE\nPS C:> Write-VerboseWithTime -Message \"The operation succeeded.\"\nPS C:>\nPS C:\\> Write-VerboseWithTime -Message \"The operation succeeded.\" -Verbose\nVERBOSE: 1/27/2014 11:02:37 AM - The operation succeeded.\n\n.EXAMPLE\nPS C:\\ps-test> \"The operation succeeded.\" | Write-VerboseWithTime -Verbose\nVERBOSE: 1/27/2014 11:01:38 AM - The operation succeeded.\n\n.LINK\nWrite-Verbose\n#>\nfunction Write-VerboseWithTime\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Position=0, Mandatory = $true, ValueFromPipeline = $true)]\n        [String]\n        $Message\n    )\n\n    $Message | Format-DevTestMessageWithTime | Write-Verbose\n}\n\n\n<#\n.SYNOPSIS\nWrites a host message prefixed with the current time.\n\n.DESCRIPTION\nThis function writes a message to the host program (Write-Host) prefixed with the current time. The effect of writing to the host program varies. Most programs that host Windows PowerShell write these messages to standard output.\n\n.PARAMETER  Message\nSpecifies the base message without the date. You can pipe the message string to the function.\n\n.INPUTS\nSystem.String\n\n.OUTPUTS\nNone. The function writes the message to the host program.\n\n.EXAMPLE\nPS C:> Write-HostWithTime -Message \"The operation succeeded.\"\n1/27/2014 11:02:37 AM - The operation succeeded.\n\n.LINK\nWrite-Host\n#>\nfunction Write-HostWithTime\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Position=0, Mandatory = $true, ValueFromPipeline = $true)]\n        [String]\n        $Message\n    )\n    \n    if ((Get-Variable SendHostMessagesToOutput -Scope Global -ErrorAction SilentlyContinue) -and $Global:SendHostMessagesToOutput)\n    {\n        if (!(Get-Variable -Scope Global AzureWebAppPublishOutput -ErrorAction SilentlyContinue) -or !$Global:AzureWebAppPublishOutput)\n        {\n            New-Variable -Name AzureWebAppPublishOutput -Value @() -Scope Global -Force\n        }\n\n        $Global:AzureWebAppPublishOutput += $Message | Format-DevTestMessageWithTime\n    }\n    else \n    {\n        $Message | Format-DevTestMessageWithTime | Write-Host\n    }\n}\n\n\n<#\n.SYNOPSIS\nReturns $true if a property or method is a member of the object. Otherwise, $false.\n\n.DESCRIPTION\nReturns $true if the property or method is a member of the object. This function returns $false for static methods of the class and for views, such as PSBase and PSObject.\n\n.PARAMETER  Object\nSpecifies the object in the test. Enter a variable that contains an object or an expression that returns an object. You cannot specify types, such as [DateTime] or pipe objects to this function.\n\n.PARAMETER  Member\nSpecifies the name of the property or method in the test. When specifying a method, omit parentheses that follow the method name.\n\n.INPUTS\nNone. This function does not take input from the pipeline.\n\n.OUTPUTS\nSystem.Boolean\n\n.EXAMPLE\nPS C:\\> Test-Member -Object (Get-Date) -Member DayOfWeek\nTrue\n\n.EXAMPLE\nPS C:\\> $date = Get-Date\nPS C:\\> Test-Member -Object $date -Member AddDays\nTrue\n\n.EXAMPLE\nPS C:\\> [DateTime]::IsLeapYear((Get-Date).Year)\nTrue\nPS C:\\> Test-Member -Object (Get-Date) -Member IsLeapYear\nFalse\n\n.LINK\nGet-Member\n#>\nfunction Test-Member\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [Object]\n        $Object,\n\n        [Parameter(Mandatory = $true)]\n        [String]\n        $Member\n    )\n\n    return $null -ne ($Object | Get-Member -Name $Member)\n}\n\n\n<#\n.SYNOPSIS\nReturns $true if the version of the Azure module is 0.7.4 or later. Else, $false.\n\n.DESCRIPTION\nTest-AzureModuleVersion returns $true if the version of the Azure module is 0.7.4 or later. It returns $false if the module isn't installed or is an earlier version. This function has no parameters.\n\n.INPUTS\nNone\n\n.OUTPUTS\nSystem.Boolean\n\n.EXAMPLE\nPS C:\\> Get-Module Azure -ListAvailable\nPS C:\\> #No module\nPS C:\\> Test-AzureModuleVersion\nFalse\n\n.EXAMPLE\nPS C:\\> (Get-Module Azure -ListAvailable).Version\n\nMajor  Minor  Build  Revision\n-----  -----  -----  --------\n0      7      4      -1\n\nPS C:\\> Test-AzureModuleVersion\nTrue\n\n.LINK\nGet-Module\n\n.LINK\nPSModuleInfo object (http://msdn.microsoft.com/en-us/library/system.management.automation.psmoduleinfo(v=vs.85).aspx)\n#>\nfunction Test-AzureModuleVersion\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [ValidateNotNull()]\n        [System.Version]\n        $Version\n    )\n\n    return ($Version.Major -gt 0) -or ($Version.Minor -gt 7) -or ($Version.Minor -eq 7 -and $Version.Build -ge 4)\n}\n\n\n<#\n.SYNOPSIS\nReturns $true if the installed Azure module version is 0.7.4 or later.\n\n.DESCRIPTION\nTest-AzureModule returns $true if the installed Azure module version is 0.7.4 or later. Returns $false if the module isn't installed or is an earlier version. This function has no parameters.\n\n.INPUTS\nNone\n\n.OUTPUTS\nSystem.Boolean\n\n.EXAMPLE\nPS C:\\> Get-Module Azure -ListAvailable\nPS C:\\> #No module\nPS C:\\> Test-AzureModule\nFalse\n\n.EXAMPLE\nPS C:\\> (Get-Module Azure -ListAvailable).Version\n\nMajor  Minor  Build  Revision\n-----  -----  -----  --------\n    0      7      4      -1\n\nPS C:\\> Test-AzureModule\nTrue\n\n.LINK\nGet-Module\n\n.LINK\nPSModuleInfo object (http://msdn.microsoft.com/en-us/library/system.management.automation.psmoduleinfo(v=vs.85).aspx)\n#>\nfunction Test-AzureModule\n{\n    [CmdletBinding()]\n\n    $module = Get-Module -Name Azure\n\n    if (!$module)\n    {\n        $module = Get-Module -Name Azure -ListAvailable\n\n        if (!$module -or !(Test-AzureModuleVersion $module.Version))\n        {\n            return $false;\n        }\n        else\n        {\n            $ErrorActionPreference = 'Continue'\n            Import-Module -Name Azure -Global -Verbose:$false\n            $ErrorActionPreference = 'Stop'\n\n            return $true\n        }\n    }\n    else\n    {\n        return (Test-AzureModuleVersion $module.Version)\n    }\n}\n\n\n<#\n.SYNOPSIS\nSaves the current Microsoft Azure subscription in the $Script:originalSubscription variable in script scope.\n\n.DESCRIPTION\nThe Backup-Subscription function saves the current Microsoft Azure subscription (Get-AzureSubscription -Current) and its storage account, and the subscription that is changed by this script ($UserSpecifiedSubscription) and its storage account, in script scope. By saving the values, you can use a function, such as Restore-Subscription, to restore the original current subscription and storage account to current status if the current status has changed.\n\n.PARAMETER UserSpecifiedSubscription\nSpecifies the name of the subscription in which the new resources will be created and published. The function saves the names of the subscription and its storage accounts in script scope. This parameter is required.\n\n.INPUTS\nNone\n\n.OUTPUTS\nNone\n\n.EXAMPLE\nPS C:\\> Backup-Subscription -UserSpecifiedSubscription Contoso\nPS C:\\>\n\n.EXAMPLE\nPS C:\\> Backup-Subscription -UserSpecifiedSubscription Contoso -Verbose\nVERBOSE: Backup-Subscription: Start\nVERBOSE: Backup-Subscription: Original subscription is Microsoft Azure MSDN - Visual Studio Ultimate\nVERBOSE: Backup-Subscription: End\n#>\nfunction Backup-Subscription\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [AllowEmptyString()]\n        [string]\n        $UserSpecifiedSubscription\n    )\n\n    Write-VerboseWithTime 'Backup-Subscription: Start'\n\n    $Script:originalCurrentSubscription = Get-AzureSubscription -Current -ErrorAction SilentlyContinue\n    if ($Script:originalCurrentSubscription)\n    {\n        Write-VerboseWithTime ('Backup-Subscription: Original subscription is ' + $Script:originalCurrentSubscription.SubscriptionName)\n        $Script:originalCurrentStorageAccount = $Script:originalCurrentSubscription.CurrentStorageAccountName\n    }\n    \n    $Script:userSpecifiedSubscription = $UserSpecifiedSubscription\n    if ($Script:userSpecifiedSubscription)\n    {        \n        $userSubscription = Get-AzureSubscription -SubscriptionName $Script:userSpecifiedSubscription -ErrorAction SilentlyContinue\n        if ($userSubscription)\n        {\n            $Script:originalStorageAccountOfUserSpecifiedSubscription = $userSubscription.CurrentStorageAccountName\n        }        \n    }\n\n    Write-VerboseWithTime 'Backup-Subscription: End'\n}\n\n\n<#\n.SYNOPSIS\nRestores to \"current\" status the Microsoft Azure subscription that is saved in the $Script:originalSubscription variable in script scope.\n\n.DESCRIPTION\nThe Restore-Subscription function makes the subscription that is saved in the $Script:originalSubscription variable the current subscription (again). If the original subscription has a storage account, this function makes that storage account current for the current subscription.  The function restores the subscription only if there is a non-null $SubscriptionName variable in the environment. Otherwise, it exits.  If the $SubscriptionName is populated, but $Script:originalSubscription is $null, Restore-Subscription uses the Select-AzureSubscription cmdlet to clear the Current and Default settings for subscriptions in Microsoft Azure PowerShell.  This function doesn't have parameters, it takes no input, and it returns nothing (void). You can use -Verbose to write messages to the Verbose stream.\n\n.INPUTS\nNone\n\n.OUTPUTS\nNone\n\n.EXAMPLE\nPS C:\\> Restore-Subscription\nPS C:\\>\n\n.EXAMPLE\nPS C:\\> Restore-Subscription -Verbose\nVERBOSE: Restore-Subscription: Start\nVERBOSE: Restore-Subscription: End\n#>\nfunction Restore-Subscription\n{\n    [CmdletBinding()]\n    param()\n\n    Write-VerboseWithTime 'Restore-Subscription: Start'\n\n    if ($Script:originalCurrentSubscription)\n    {\n        if ($Script:originalCurrentStorageAccount)\n        {\n            Set-AzureSubscription `\n                -SubscriptionName $Script:originalCurrentSubscription.SubscriptionName `\n                -CurrentStorageAccountName $Script:originalCurrentStorageAccount\n        }\n\n        Select-AzureSubscription -SubscriptionName $Script:originalCurrentSubscription.SubscriptionName\n    }\n    else \n    {\n        Select-AzureSubscription -NoCurrent\n        Select-AzureSubscription -NoDefault\n    }\n    \n    if ($Script:userSpecifiedSubscription -and $Script:originalStorageAccountOfUserSpecifiedSubscription)\n    {\n        Set-AzureSubscription `\n            -SubscriptionName $Script:userSpecifiedSubscription `\n            -CurrentStorageAccountName $Script:originalStorageAccountOfUserSpecifiedSubscription\n    }\n\n    Write-VerboseWithTime 'Restore-Subscription: End'\n}\n\n\n<#\n.SYNOPSIS\nValidates the config file and returns a hashtable of config file values.\n\n.DESCRIPTION\nThe Read-ConfigFile function validates the JSON configuration file and returns a hash table of selected values.\n-- It begins by converting the JSON file to a PSCustomObject. The website hash table has the following keys:\n-- Location: Website location\n-- Databases: Website SQL databases\n\n.PARAMETER  ConfigurationFile\nSpecifies the path and name of the JSON configuration file for your web project. Visual Studio generates the JSON file automatically when you create a web project and stores it in the PublishScripts folder in your solution.\n\n.PARAMETER HasWebDeployPackage\nIndicates that there is a web deploy package ZIP file for the web application. To specify a value of $true, use -HasWebDeployPackage or HasWebDeployPackage:$true. To specify a value of false, use HasWebDeployPackage:$false.This parameter is required.\n\n.INPUTS\nNone. You cannot pipe input to this function.\n\n.OUTPUTS\nSystem.Collections.Hashtable\n\n.EXAMPLE\nPS C:\\> Read-ConfigFile -ConfigurationFile <path> -HasWebDeployPackage\n\n\nName                           Value                                                                                                                                                                     \n----                           -----                                                                                                                                                                     \ndatabases                      {@{connectionStringName=; databaseName=; serverName=; user=; password=}}                                                                                                  \nwebsite                        @{name=\"mysite\"; location=\"West US\";}                                                      \n#>\nfunction Read-ConfigFile\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [ValidateScript({Test-Path $_ -PathType Leaf})]\n        [String]\n        $ConfigurationFile\n    )\n\n    Write-VerboseWithTime 'Read-ConfigFile: Start'\n\n    # Get the contents of the JSON file (-raw ignores line breaks) and convert it to a PSCustomObject\n    $config = Get-Content $ConfigurationFile -Raw | ConvertFrom-Json\n\n    if (!$config)\n    {\n        throw ('Read-ConfigFile: ConvertFrom-Json failed: ' + $error[0])\n    }\n\n    # Determine whether the environmentSettings object has 'webSite' properties (regardless of the property value)\n    $hasWebsiteProperty =  Test-Member -Object $config.environmentSettings -Member 'webSite'\n\n    if (!$hasWebsiteProperty)\n    {\n        throw 'Read-ConfigFile: The configuration file does not have a webSite property.'\n    }\n\n    # Build a hash table from the values in the PSCustomObject\n    $returnObject = New-Object -TypeName Hashtable\n\n    $returnObject.Add('name', $config.environmentSettings.webSite.name)\n    $returnObject.Add('location', $config.environmentSettings.webSite.location)\n\n    if (Test-Member -Object $config.environmentSettings -Member 'databases')\n    {\n        $returnObject.Add('databases', $config.environmentSettings.databases)\n    }\n\n    Write-VerboseWithTime 'Read-ConfigFile: End'\n\n    return $returnObject\n}\n\n\n<#\n.SYNOPSIS\nCreates a Microsoft Azure Website.\n\n.DESCRIPTION\nCreates a Microsoft Azure Website with the specific name and location. This function calls the New-AzureWebsite cmdlet in the Azure module. If the subscription does not yet have a website with the specified name, this function creates the website and returns a website object. Otherwise, it returns the existing website.\n\n.PARAMETER  Name\nSpecifies a name for the new website. The name must be unique in Microsoft Azure. This parameter is required.\n\n.PARAMETER  Location\nSpecifies the location of the website. Valid values are the Microsoft Azure locations, such as \"West US\". This parameter is required.\n\n.INPUTS\nNONE.\n\n.OUTPUTS\nMicrosoft.WindowsAzure.Commands.Utilities.Websites.Services.WebEntities.Site\n\n.EXAMPLE\nAdd-AzureWebsite -Name TestSite -Location \"West US\"\n\nName       : contoso\nState      : Running\nHost Names : contoso.azurewebsites.net\n\n.LINK\nNew-AzureWebsite\n#>\nfunction Add-AzureWebsite\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [String]\n        $Name,\n\n        [Parameter(Mandatory = $true)]\n        [String]\n        $Location\n    )\n\n    Write-VerboseWithTime 'Add-AzureWebsite: Start'\n    $website = Get-AzureWebsite -Name $Name -ErrorAction SilentlyContinue\n\n    if ($website)\n    {\n        Write-HostWithTime ('Add-AzureWebsite: An existing website ' +\n        $website.Name + ' was found')\n    }\n    else\n    {\n        if (Test-AzureName -Website -Name $Name)\n        {\n            Write-ErrorWithTime ('Website {0} already exists' -f $Name)\n        }\n        else\n        {\n            $website = New-AzureWebsite -Name $Name -Location $Location\n        }\n    }\n\n    $website | Out-String | Write-VerboseWithTime\n    Write-VerboseWithTime 'Add-AzureWebsite: End'\n\n    return $website\n}\n\n<#\n.SYNOPSIS\nReturns $True when the URL is absolute and its scheme is https.\n\n.DESCRIPTION\nThe Test-HttpsUrl function converts the input URL to a System.Uri object. Returns $True when the URL is absolute (not relative) and its scheme is https. If either is false, or the input string cannot be converted to a URL, the function returns $false.\n\n.PARAMETER Url\nSpecifies the URL to test. Enter a URL string,\n\n.INPUTS\nNONE.\n\n.OUTPUTS\nSystem.Boolean\n\n.EXAMPLE\nPS C:\\>$profile.publishUrl\nwaws-prod-bay-001.publish.azurewebsites.windows.net:443\n\nPS C:\\>Test-HttpsUrl -Url 'waws-prod-bay-001.publish.azurewebsites.windows.net:443'\nFalse\n#>\nfunction Test-HttpsUrl\n{\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [String]\n        $Url\n    )\n\n    # If $uri cannot be converted to a System.Uri object, Test-HttpsUrl returns $false\n    $uri = $Url -as [System.Uri]\n\n    return $uri.IsAbsoluteUri -and $uri.Scheme -eq 'https'\n}\n\n\n<#\n.SYNOPSIS\nCreates a string that lets you connect to a Microsoft Azure SQL database.\n\n.DESCRIPTION\nThe Get-AzureSQLDatabaseConnectionString function assembles a connection string to connect to a Microsoft Azure SQL database.\n\n.PARAMETER  DatabaseServerName\nSpecifies the name of an existing database server in the Microsoft Azure subscription. All Microsoft Azure SQL databases must be associated with a SQL database server. To get the server name, use the Get-AzureSqlDatabaseServer cmdlet (Azure module). This parameter is required.\n\n.PARAMETER  DatabaseName\nSpecifies the name for the SQL database. This can be an existing SQL database or a name used for a new SQL database. This parameter is required.\n\n.PARAMETER  Username\nSpecifies the name of the SQL database administrator. The username will be $Username@DatabaseServerName. This parameter is required.\n\n.PARAMETER  Password\nSpecifies a password for the SQL database administrator. Enter a password in plain text. Secure strings are not permitted. This parameter is required.\n\n.INPUTS\nNone.\n\n.OUTPUTS\nSystem.String\n\n.EXAMPLE\nPS C:\\> $ServerName = (Get-AzureSqlDatabaseServer).ServerName[0]\nPS C:\\> Get-AzureSQLDatabaseConnectionString -DatabaseServerName $ServerName `\n        -DatabaseName 'testdb' -UserName 'admin'  -Password 'password'\n\nServer=tcp:testserver.database.windows.net,1433;Database=testdb;User ID=admin@testserver;Password=password;Trusted_Connection=False;Encrypt=True;Connection Timeout=20;\n#>\nfunction Get-AzureSQLDatabaseConnectionString\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [String]\n        $DatabaseServerName,\n\n        [Parameter(Mandatory = $true)]\n        [String]\n        $DatabaseName,\n\n        [Parameter(Mandatory = $true)]\n        [String]\n        $UserName,\n\n        [Parameter(Mandatory = $true)]\n        [String]\n        $Password\n    )\n\n    return ('Server=tcp:{0}.database.windows.net,1433;Database={1};' +\n           'User ID={2}@{0};' +\n           'Password={3};' +\n           'Trusted_Connection=False;' +\n           'Encrypt=True;' +\n           'Connection Timeout=20;') `\n           -f $DatabaseServerName, $DatabaseName, $UserName, $Password\n}\n\n\n<#\n.SYNOPSIS\nCreates Microsoft Azure SQL databases from the values in the JSON configuation file that Visual Studio generates.\n\n.DESCRIPTION\nThe Add-AzureSQLDatabases function takes information from the databases section of the JSON file. This function, Add-AzureSQLDatabases (plural), calls the Add-AzureSQLDatabase (singular) function for each SQL database in the JSON file. Add-AzureSQLDatabase (singular) calls the New-AzureSqlDatabase cmdlet (Azure module), which creates the SQL databases. This function does not return a database object. It returns a hashtable of values that were used to create the databases.\n\n.PARAMETER DatabaseConfig\n Takes an array of PSCustomObjects that originate in the JSON file that the Read-ConfigFile function returns when the JSON file has a website property. It includes the environmentSettings.databases properties. You can pipe the list to this function.\nPS C:\\> $config = Read-ConfigFile <name>.json\nPS C:\\> $DatabaseConfig = $config.databases| where {$_.connectionStringName}\nPS C:\\> $DatabaseConfig\nconnectionStringName: Default Connection\ndatabasename : TestDB1\nedition   :\nsize     : 1\ncollation  : SQL_Latin1_General_CP1_CI_AS\nservertype  : New SQL Database Server\nservername  : r040tvt2gx\nuser     : dbuser\npassword   : Test.123\nlocation   : West US\n\n.PARAMETER  DatabaseServerPassword\nSpecifies the password for the SQL database server administrator. Enter a hashtable with Name and Password keys. The value of Name is the name of the SQL database server. The value of Password is the administrator password. For example: @Name = \"TestDB1\"; Password = \"password\" This parameter is optional. If you omit it or the SQL database server name doesn't match the value of the serverName property of the $DatabaseConfig object, the function uses the Password property of the $DatabaseConfig object for the SQL database in the connection string.\n\n.PARAMETER CreateDatabase\nVerifies that you want to create a database. This parameter is optional.\n\n.INPUTS\nSystem.Collections.Hashtable[]\n\n.OUTPUTS\nSystem.Collections.Hashtable\n\n.EXAMPLE\nPS C:\\> $config = Read-ConfigFile <name>.json\nPS C:\\> $DatabaseConfig = $config.databases| where {$_.connectionStringName}\nPS C:\\> $DatabaseConfig | Add-AzureSQLDatabases\n\nName                           Value\n----                           -----\nConnectionString               Server=tcp:testdb1.database.windows.net,1433;Database=testdb;User ID=admin@testdb1;Password=password;Trusted_Connection=False;Encrypt=True;Connection Timeout=20;\nName                           Default Connection\nType                           SQLAzure\n\n.LINK\nGet-AzureSQLDatabaseConnectionString\n\n.LINK\nCreate-AzureSQLDatabase\n#>\nfunction Add-AzureSQLDatabases\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]\n        [PSCustomObject]\n        $DatabaseConfig,\n\n        [Parameter(Mandatory = $false)]\n        [AllowNull()]\n        [Hashtable[]]\n        $DatabaseServerPassword,\n\n        [Parameter(Mandatory = $false)]\n        [Switch]\n        $CreateDatabase = $false\n    )\n\n    begin\n    {\n        Write-VerboseWithTime 'Add-AzureSQLDatabases: Start'\n    }\n    process\n    {\n        Write-VerboseWithTime ('Add-AzureSQLDatabases: Creating ' + $DatabaseConfig.databaseName)\n\n        if ($CreateDatabase)\n        {\n            # Creates a new SQL database with the DatabaseConfig values (unless one already exists)\n            # The command output is suppressed.\n            Add-AzureSQLDatabase -DatabaseConfig $DatabaseConfig | Out-Null\n        }\n\n        $serverPassword = $null\n        if ($DatabaseServerPassword)\n        {\n            foreach ($credential in $DatabaseServerPassword)\n            {\n               if ($credential.Name -eq $DatabaseConfig.serverName)\n               {\n                   $serverPassword = $credential.password             \n                   break\n               }\n            }               \n        }\n\n        if (!$serverPassword)\n        {\n            $serverPassword = $DatabaseConfig.password\n        }\n\n        return @{\n            Name = $DatabaseConfig.connectionStringName;\n            Type = 'SQLAzure';\n            ConnectionString = Get-AzureSQLDatabaseConnectionString `\n                -DatabaseServerName $DatabaseConfig.serverName `\n                -DatabaseName $DatabaseConfig.databaseName `\n                -UserName $DatabaseConfig.user `\n                -Password $serverPassword }\n    }\n    end\n    {\n        Write-VerboseWithTime 'Add-AzureSQLDatabases: End'\n    }\n}\n\n\n<#\n.SYNOPSIS\nCreates a new Microsoft Azure SQL database.\n\n.DESCRIPTION\nThe Add-AzureSQLDatabase function creates a Microsoft Azure SQL database from the data in the JSON configuration file that Visual Studio generates and returns the new database. If the subscription already has a SQL database with the specified database name in the specified SQL database server, the function returns the existing database. This function calls the New-AzureSqlDatabase cmdlet (Azure module), which actually creates the SQL database.\n\n.PARAMETER DatabaseConfig\nTakes a PSCustomObject that originates in the JSON configuration file that the Read-ConfigFile function returns when the JSON file has a website property. It includes the environmentSettings.databases properties. You cannot pipe the object to this function. Visual Studio generates a JSON configuration file for all web projects and stores it in the PublishScripts folder of your solution.\n\n.INPUTS\nNone. This function does not take input from the pipeline\n\n.OUTPUTS\nMicrosoft.WindowsAzure.Commands.SqlDatabase.Services.Server.Database\n\n.EXAMPLE\nPS C:\\> $config = Read-ConfigFile <name>.json\nPS C:\\> $DatabaseConfig = $config.databases | where connectionStringName\nPS C:\\> $DatabaseConfig\n\nconnectionStringName    : Default Connection\ndatabasename : TestDB1\nedition      :\nsize         : 1\ncollation    : SQL_Latin1_General_CP1_CI_AS\nservertype   : New SQL Database Server\nservername   : r040tvt2gx\nuser         : dbuser\npassword     : Test.123\nlocation     : West US\n\nPS C:\\> Add-AzureSQLDatabase -DatabaseConfig $DatabaseConfig\n\n.LINK\nAdd-AzureSQLDatabases\n\n.LINK\nNew-AzureSQLDatabase\n#>\nfunction Add-AzureSQLDatabase\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [ValidateNotNull()]\n        [Object]\n        $DatabaseConfig\n    )\n\n    Write-VerboseWithTime 'Add-AzureSQLDatabase: Start'\n\n    # Fail if the parameter value doesn't have the serverName property, or the serverName property value isn't populated.\n    if (-not (Test-Member $DatabaseConfig 'serverName') -or -not $DatabaseConfig.serverName)\n    {\n        throw 'Add-AzureSQLDatabase: The database serverName (required) is missing from the DatabaseConfig value.'\n    }\n\n    # Fail if the parameter value doesn't have the databasename property, or the databasename property value isn't populated.\n    if (-not (Test-Member $DatabaseConfig 'databaseName') -or -not $DatabaseConfig.databaseName)\n    {\n        throw 'Add-AzureSQLDatabase: The databasename (required) is missing from the DatabaseConfig value.'\n    }\n\n    $DbServer = $null\n\n    if (Test-HttpsUrl $DatabaseConfig.serverName)\n    {\n        $absoluteDbServer = $DatabaseConfig.serverName -as [System.Uri]\n        $subscription = Get-AzureSubscription -Current -ErrorAction SilentlyContinue\n\n        if ($subscription -and $subscription.ServiceEndpoint -and $subscription.SubscriptionId)\n        {\n            $absoluteDbServerRegex = 'https:\\/\\/{0}\\/{1}\\/services\\/sqlservers\\/servers\\/(.+)\\.database\\.windows\\.net\\/databases' -f `\n                                     $subscription.serviceEndpoint.Host, $subscription.SubscriptionId\n\n            if ($absoluteDbServer -match $absoluteDbServerRegex -and $Matches.Count -eq 2)\n            {\n                 $DbServer = $Matches[1]\n            }\n        }\n    }\n\n    if (!$DbServer)\n    {\n        $DbServer = $DatabaseConfig.serverName\n    }\n\n    $db = Get-AzureSqlDatabase -ServerName $DbServer -DatabaseName $DatabaseConfig.databaseName -ErrorAction SilentlyContinue\n\n    if ($db)\n    {\n        Write-HostWithTime ('Create-AzureSQLDatabase: Using existing database ' + $db.Name)\n        $db | Out-String | Write-VerboseWithTime\n    }\n    else\n    {\n        $param = New-Object -TypeName Hashtable\n        $param.Add('serverName', $DbServer)\n        $param.Add('databaseName', $DatabaseConfig.databaseName)\n\n        if ((Test-Member $DatabaseConfig 'size') -and $DatabaseConfig.size)\n        {\n            $param.Add('MaxSizeGB', $DatabaseConfig.size)\n        }\n        else\n        {\n            $param.Add('MaxSizeGB', 1)\n        }\n\n        # If the $DatabaseConfig object has a collation property and it's not null or empty\n        if ((Test-Member $DatabaseConfig 'collation') -and $DatabaseConfig.collation)\n        {\n            $param.Add('Collation', $DatabaseConfig.collation)\n        }\n\n        # If the $DatabaseConfig object has an edition property and it's not null or empty\n        if ((Test-Member $DatabaseConfig 'edition') -and $DatabaseConfig.edition)\n        {\n            $param.Add('Edition', $DatabaseConfig.edition)\n        }\n\n        # Write the hash table to the Verbose stream\n        $param | Out-String | Write-VerboseWithTime\n        # Call New-AzureSqlDatabase with splatting (suppress the output)\n        $db = New-AzureSqlDatabase @param\n    }\n\n    Write-VerboseWithTime 'Add-AzureSQLDatabase: End'\n    return $db\n}\n"
  },
  {
    "path": "Samples/WebApp/PublishScripts/Configurations/WebApp-WAWS-dev.json",
    "content": "{\n    \"environmentSettings\": {\n        \"webSite\": {\n            \"name\": \"WebApp8882\",\n            \"location\": \"East US\"\n        },\n        \"databases\": [\n            {\n                \"connectionStringName\": \"\",\n                \"databaseName\": \"\",\n                \"serverName\": \"\",\n                \"user\": \"\",\n                \"password\": \"\",\n                \"edition\": \"\",\n                \"size\": \"\",\n                \"collation\": \"\"\n            }\n        ]\n    }\n}\n"
  },
  {
    "path": "Samples/WebApp/PublishScripts/Publish-WebApplicationWebsite.ps1",
    "content": "﻿#Requires -Version 3.0\n\n<#\n.SYNOPSIS\nCreates and deploys a Microsoft Azure Website for a Visual Studio web project.\nFor more detailed documentation go to: http://go.microsoft.com/fwlink/?LinkID=394471 \n\n.EXAMPLE\nPS C:\\> .\\Publish-WebApplicationWebSite.ps1 `\n-Configuration .\\Configurations\\WebApplication1-WAWS-dev.json `\n-WebDeployPackage ..\\WebApplication1\\WebApplication1.zip `\n-Verbose\n\n#>\n[CmdletBinding(HelpUri = 'http://go.microsoft.com/fwlink/?LinkID=391696')]\nparam\n(\n    [Parameter(Mandatory = $true)]\n    [ValidateScript({Test-Path $_ -PathType Leaf})]\n    [String]\n    $Configuration,\n\n    [Parameter(Mandatory = $false)]\n    [String]\n    $SubscriptionName,\n\n    [Parameter(Mandatory = $false)]\n    [ValidateScript({Test-Path $_ -PathType Leaf})]\n    [String]\n    $WebDeployPackage,\n\n    [Parameter(Mandatory = $false)]\n    [ValidateScript({ !($_ | Where-Object { !$_.Contains('Name') -or !$_.Contains('Password')}) })]\n    [Hashtable[]]\n    $DatabaseServerPassword,\n\n    [Parameter(Mandatory = $false)]\n    [Switch]\n    $SendHostMessagesToOutput = $false\n)\n\n\nfunction New-WebDeployPackage\n{\n    #Write a function to build and package your web application\n\n    #To build your web application, use MsBuild.exe. For help, see MSBuild Command-Line Reference at: http://go.microsoft.com/fwlink/?LinkId=391339\n}\n\nfunction Test-WebApplication\n{\n    #Edit this function to run unit tests on your web application\n\n    #Write a function to run unit tests on your web application, use VSTest.Console.exe. For help, see VSTest.Console Command-Line Reference at http://go.microsoft.com/fwlink/?LinkId=391340\n}\n\nfunction New-AzureWebApplicationWebsiteEnvironment\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [Object]\n        $Configuration,\n\n        [Parameter (Mandatory = $false)]\n        [AllowNull()]\n        [Hashtable[]]\n        $DatabaseServerPassword\n    )\n       \n    Add-AzureWebsite -Name $Config.name -Location $Config.location | Out-String | Write-HostWithTime\n    # Create the SQL databases. The connection string is used for deployment.\n    $connectionString = New-Object -TypeName Hashtable\n    \n    if ($Config.Contains('databases'))\n    {\n        @($Config.databases) |\n            Where-Object {$_.connectionStringName -ne ''} |\n            Add-AzureSQLDatabases -DatabaseServerPassword $DatabaseServerPassword -CreateDatabase |\n            ForEach-Object { $connectionString.Add($_.Name, $_.ConnectionString) }           \n    }\n    \n    return @{ConnectionString = $connectionString}   \n}\n\nfunction Publish-AzureWebApplicationToWebsite\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [Object]\n        $Configuration,\n\n        [Parameter(Mandatory = $false)]\n        [AllowNull()]\n        [Hashtable]\n        $ConnectionString,\n\n        [Parameter(Mandatory = $true)]\n        [ValidateScript({Test-Path $_ -PathType Leaf})]\n        [String]\n        $WebDeployPackage\n    )\n\n    if ($ConnectionString -and $ConnectionString.Count -gt 0)\n    {\n        Publish-AzureWebsiteProject `\n            -Name $Config.name `\n            -Package $WebDeployPackage `\n            -ConnectionString $ConnectionString\n    }\n    else\n    {\n        Publish-AzureWebsiteProject `\n            -Name $Config.name `\n            -Package $WebDeployPackage\n    }\n}\n\n\n# Script main routine\nSet-StrictMode -Version 3\n\nRemove-Module AzureWebSitePublishModule -ErrorAction SilentlyContinue\n$scriptDirectory = Split-Path -Parent $PSCmdlet.MyInvocation.MyCommand.Definition\nImport-Module ($scriptDirectory + '\\AzureWebSitePublishModule.psm1') -Scope Local -Verbose:$false\n\nNew-Variable -Name VMWebDeployWaitTime -Value 30 -Option Constant -Scope Script \nNew-Variable -Name AzureWebAppPublishOutput -Value @() -Scope Global -Force\nNew-Variable -Name SendHostMessagesToOutput -Value $SendHostMessagesToOutput -Scope Global -Force\n\ntry\n{\n    $originalErrorActionPreference = $Global:ErrorActionPreference\n    $originalVerbosePreference = $Global:VerbosePreference\n    \n    if ($PSBoundParameters['Verbose'])\n    {\n        $Global:VerbosePreference = 'Continue'\n    }\n    \n    $scriptName = $MyInvocation.MyCommand.Name + ':'\n    \n    Write-VerboseWithTime ($scriptName + ' Start')\n    \n    $Global:ErrorActionPreference = 'Stop'\n    Write-VerboseWithTime ('{0} $ErrorActionPreference is set to {1}' -f $scriptName, $ErrorActionPreference)\n    \n    Write-Debug ('{0}: $PSCmdlet.ParameterSetName = {1}' -f $scriptName, $PSCmdlet.ParameterSetName)\n\n    # Save the current subscription. It will be restored to Current status later in the script\n    Backup-Subscription -UserSpecifiedSubscription $SubscriptionName\n    \n    # Verify that you have the Azure module, Version 0.7.4 or later.\n    if (-not (Test-AzureModule))\n    {\n         throw 'You have an outdated version of Microsoft Azure PowerShell. To install the latest version, go to http://go.microsoft.com/fwlink/?LinkID=320552 .'\n    }\n    \n    if ($SubscriptionName)\n    {\n\n        # If you provided a subscription name, verify that the subscription exists in your account.\n        if (!(Get-AzureSubscription -SubscriptionName $SubscriptionName))\n        {\n            throw (\"{0}: Cannot find the subscription name $SubscriptionName\" -f $scriptName)\n\n        }\n\n        # Set the specified subscription to current.\n        Select-AzureSubscription -SubscriptionName $SubscriptionName | Out-Null\n\n        Write-VerboseWithTime ('{0}: Subscription is set to {1}' -f $scriptName, $SubscriptionName)\n    }\n\n    $Config = Read-ConfigFile $Configuration \n\n    #Build and package your web application\n    New-WebDeployPackage\n\n    #Run unit tests on your web application\n    Test-WebApplication\n\n    #Create Azure environment described in the JSON configuration file\n    $newEnvironmentResult = New-AzureWebApplicationWebsiteEnvironment -Configuration $Config -DatabaseServerPassword $DatabaseServerPassword\n\n    #Deploy Web Application package if $WebDeployPackage is specified by the user \n    if($WebDeployPackage)\n    {\n        Publish-AzureWebApplicationToWebsite `\n            -Configuration $Config `\n            -ConnectionString $newEnvironmentResult.ConnectionString `\n            -WebDeployPackage $WebDeployPackage\n    }\n}\nfinally\n{\n    $Global:ErrorActionPreference = $originalErrorActionPreference\n    $Global:VerbosePreference = $originalVerbosePreference\n\n    # Restore the original current subscription to Current status\n    Restore-Subscription\n\n    Write-Output $Global:AzureWebAppPublishOutput    \n    $Global:AzureWebAppPublishOutput = @()\n}\n"
  },
  {
    "path": "Samples/WebApp/WebApp/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.6\" />\n    </startup>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Newtonsoft.Json\" publicKeyToken=\"30ad4fe6b2a6aeed\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-10.0.0.0\" newVersion=\"10.0.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.Owin\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-3.1.0.0\" newVersion=\"3.1.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>\n"
  },
  {
    "path": "Samples/WebApp/WebApp/App.cs",
    "content": "﻿#region\n\nusing System;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Sockets;\nusing System.Threading.Tasks;\nusing Etg.Yams.Client;\n\n#endregion\n\nnamespace WebApp\n{\n    public class App\n    {\n        public static string Id;\n        public static string Version;\n        public static string ClusterId;\n        public static string InstanceId;\n\n        private static readonly TimeSpan HeartBeatPeriod = TimeSpan.FromSeconds(5);\n\n        public static void Main(string[] args)\n        {\n            MainAsync(args).Wait();\n        }\n\n        private static async Task MainAsync(string[] args)\n        {\n            Id = args[0];\n            Version = args[1];\n            ClusterId = args[2];\n            InstanceId = args[3];\n\n            Version version = new Version(Version);\n            string apiVersion = $\"{version}\";\n            string baseUrl = $\"http://{GetIpAddress()}:8008/{Id}/{apiVersion}\";\n            Console.WriteLine(\"Url is: \" + baseUrl);\n\n            // Start OWIN host \n            Microsoft.Owin.Hosting.WebApp.Start<Startup>(url: baseUrl);\n            Console.WriteLine(\"WebApp has been started successfully\");\n            \n            var yamsClientConfig = new YamsClientConfigBuilder(args).Build();\n            var yamsClientFactory = new YamsClientFactory();\n            IYamsClient yamsClient = yamsClientFactory.CreateYamsClient(yamsClientConfig);\n\n            await yamsClient.Connect();\n            await yamsClient.SendInitializationDoneMessage();\n\n            var exitMessageReceived = false;\n            yamsClient.ExitMessageReceived += (sender, eventArgs) => { exitMessageReceived = true; };\n\n            while (!exitMessageReceived)\n            {\n                await Task.Delay(HeartBeatPeriod);\n                await yamsClient.SendHeartBeat();\n            }\n        }\n\n        private static string GetIpAddress()\n        {\n            var host = Dns.GetHostEntry(Dns.GetHostName());\n            return host.AddressList.First(x => x.AddressFamily == AddressFamily.InterNetwork).ToString();\n        }\n    }\n}"
  },
  {
    "path": "Samples/WebApp/WebApp/AppConfig.json",
    "content": "﻿{\n  \"ExeName\": \"WebApp.exe\",\n  \"ExeArgs\": \"${Id} ${Version} ${ClusterId} ${InstanceId}\",\n  \"GracefulShutdown\": true,\n  \"MonitorHealth\": true,\n  \"MonitorInitialization\": true\n}\n"
  },
  {
    "path": "Samples/WebApp/WebApp/ApplicationController.cs",
    "content": "﻿using System.Threading.Tasks;\nusing System.Web.Http;\nusing Newtonsoft.Json.Linq;\n\nnamespace WebApp\n{\n    [RoutePrefix(\"application\")]\n    public class ApplicationController : ApiController\n    {\n        [Route(\"info\")]\n        public JObject GetInfo()\n        {\n            string json = $@\"\n                {{\n                    'Id': '{App.Id}',\n                    'Version': '{App.Version}',\n                    'ClusterId': '{App.ClusterId}',\n                    'InstanceId': '{App.InstanceId}'\n                }}\n                \";\n\n            return JObject.Parse(json);\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/WebApp/WebApp/CoinFlipController.cs",
    "content": "﻿using System;\nusing System.Web.Http;\n\nnamespace WebApp\n{\n    [RoutePrefix(\"coinflip\")]\n    public class CoinFlipController : ApiController\n    {\n        private static readonly Random Random = new Random();\n\n        [HttpGet]\n        [Route(\"next\")]\n        public string Run()\n        {\n            if (Random.Next(2) == 0)\n            {\n                return \"Heads\";\n            }\n            return \"Tails\";\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/WebApp/WebApp/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"WebApp\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"WebApp\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2015\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"e09bbf9f-7e9d-4635-93b8-1d491adb8b90\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/WebApp/WebApp/Startup.cs",
    "content": "﻿using System;\nusing System.Web.Http;\nusing Owin;\n\nnamespace WebApp\n{\n    class Startup\n    {\n        // This code configures Web API. The Startup class is specified as a type\n        // parameter in the WebApp.Start method.\n        public void Configuration(IAppBuilder appBuilder)\n        {\n            // Configure Web API for self-host. \n            HttpConfiguration config = new HttpConfiguration();\n            config.MapHttpAttributeRoutes();\n            config.Routes.MapHttpRoute(\n                name: \"DefaultApi\",\n                routeTemplate: \"api/{controller}/{id}\",\n                defaults: new { id = RouteParameter.Optional }\n            );\n            config.EnsureInitialized();\n            appBuilder.UseWebApi(config);\n\n            Console.WriteLine(\"Available Apis:\");\n            foreach (var api in config.Services.GetApiExplorer().ApiDescriptions)\n            {\n                Console.WriteLine(\"{0} {1}\", api.HttpMethod, api.RelativePath);\n            }\n        } \n    }\n}\n"
  },
  {
    "path": "Samples/WebApp/WebApp/WebApp.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{B93B7872-46CC-4386-B7A0-C6068A4A2659}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>WebApp</RootNamespace>\n    <AssemblyName>WebApp</AssemblyName>\n    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\CommandLineParser.1.9.71\\lib\\net45\\CommandLine.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Etg.Yams.Client, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.Client.1.0.0\\lib\\net451\\Etg.Yams.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Etg.Yams.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.Client.1.0.0\\lib\\net451\\Etg.Yams.Common.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Etg.Yams.Ipc, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.Client.1.0.0\\lib\\net451\\Etg.Yams.Ipc.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Owin.3.1.0\\lib\\net45\\Microsoft.Owin.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Owin.Host.HttpListener, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Owin.Host.HttpListener.3.1.0\\lib\\net45\\Microsoft.Owin.Host.HttpListener.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Owin.Hosting, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Owin.Hosting.3.1.0\\lib\\net45\\Microsoft.Owin.Hosting.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.10.0.3\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Owin.1.0\\lib\\net40\\Owin.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.AspNet.WebApi.Client.5.2.3\\lib\\net45\\System.Net.Http.Formatting.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.AspNet.WebApi.Core.5.2.3\\lib\\net45\\System.Web.Http.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.AspNet.WebApi.Owin.5.2.3\\lib\\net45\\System.Web.Http.Owin.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"App.cs\" />\n    <Compile Include=\"CoinFlipController.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"ApplicationController.cs\" />\n    <Compile Include=\"Startup.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Include=\"AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "Samples/WebApp/WebApp/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"net46\" />\n  <package id=\"Etg.Yams.Client\" version=\"1.0.0\" targetFramework=\"net46\" />\n  <package id=\"Microsoft.AspNet.WebApi.Client\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.Core\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.Owin\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.AspNet.WebApi.OwinSelfHost\" version=\"5.2.3\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Owin\" version=\"3.1.0\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Owin.Host.HttpListener\" version=\"3.1.0\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Owin.Hosting\" version=\"3.1.0\" targetFramework=\"net45\" />\n  <package id=\"Newtonsoft.Json\" version=\"10.0.3\" targetFramework=\"net45\" />\n  <package id=\"Owin\" version=\"1.0\" targetFramework=\"net45\" />\n</packages>"
  },
  {
    "path": "Samples/WebApp/WebApp.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2013\nVisualStudioVersion = 12.0.31101.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"WebApp\", \"WebApp\\WebApp.csproj\", \"{B93B7872-46CC-4386-B7A0-C6068A4A2659}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B93B7872-46CC-4386-B7A0-C6068A4A2659}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B93B7872-46CC-4386-B7A0-C6068A4A2659}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B93B7872-46CC-4386-B7A0-C6068A4A2659}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B93B7872-46CC-4386-B7A0-C6068A4A2659}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Samples/YamsStudio/AddNewApplicationDialog.xaml",
    "content": "﻿<Window x:Class=\"YamsStudio.AddNewApplicationDialog\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n        xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n        xmlns:controls=\"clr-namespace:YamsStudio\"\n        xmlns:local=\"clr-namespace:YamsStudio\"\n        mc:Ignorable=\"d\"\n        Title=\"Add New Application\" SizeToContent=\"WidthAndHeight\" WindowStartupLocation=\"CenterOwner\"\n        ContentRendered=\"Window_ContentRendered\">\n    <Grid Margin=\"15\">\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"Auto\" />\n            <ColumnDefinition Width=\"*\" />\n        </Grid.ColumnDefinitions>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n        </Grid.RowDefinitions>\n        <StackPanel>\n            <Label x:Name=\"lbl_ApplicationName\" Content=\"Name:\"/>\n            <TextBox x:Name=\"txt_AplicationName\" MinWidth=\"250\" RenderTransformOrigin=\"0.542,-0.797\"/>\n            <Label x:Name=\"lbl_Version\" Content=\"Version:\"/>\n            <TextBox x:Name=\"txt_Version\" MinWidth=\"250\"/>\n            <Label x:Name=\"lbl_DeploymentId\" Content=\"DeploymentId:\"/>\n            <TextBox x:Name=\"txt_DeploymentId\" Grid.Row=\"1\" MinWidth=\"250\"/>            \n            <Label x:Name=\"lbl_BinariesDirPath\" Content=\"Binaries Path:\"/>\n            <controls:SelectDirectoryControl Grid.ColumnSpan=\"2\" x:Name=\"uc_SelectBinaries\"></controls:SelectDirectoryControl>\n        </StackPanel>\n\n        <WrapPanel Grid.Row=\"2\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Right\" Margin=\"0,15,0,0\">\n            <Button IsDefault=\"True\" Name=\"btn_DialogOk\" Click=\"OnOk\" MinWidth=\"60\" Margin=\"0,0,10,0\">_Ok</Button>\n            <Button IsCancel=\"True\" MinWidth=\"60\">_Cancel</Button>\n        </WrapPanel>\n    </Grid>\n</Window>\n"
  },
  {
    "path": "Samples/YamsStudio/AddNewApplicationDialog.xaml.cs",
    "content": "﻿using System;\nusing System.Windows;\nusing System.Windows.Forms;\n\nnamespace YamsStudio\n{\n    /// <summary>\n    /// Interaction logic for AddNewApplicationDialog.xaml\n    /// </summary>\n    public partial class AddNewApplicationDialog : Window\n    {\n        public AddNewApplicationDialog(string appId, string version, string deploymentId, string binariesPath=null)\n        {\n            InitializeComponent();\n\n            txt_AplicationName.Text = appId;\n            txt_Version.Text = version;\n            txt_DeploymentId.Text = deploymentId;\n        }\n\n        public AddNewApplicationDialog() : this(null, null, null)\n        {\n        }\n\n        public AddNewApplicationDialog(string appId) : this(appId, null, null)\n        {\n        }\n\n        public AddNewApplicationDialog(string appId, string version) : this(appId, version, null)\n        {\n        }\n\n        private void Window_ContentRendered(object sender, EventArgs e)\n        {\n            txt_AplicationName.SelectAll();\n            txt_AplicationName.Focus();\n        }\n\n        private void OnOk(object sender, RoutedEventArgs e)\n        {\n            this.DialogResult = true;\n        }\n\n        public string ApplicationName => txt_AplicationName.Text;\n        public string Version => txt_Version.Text;\n        public string BinariesPath => uc_SelectBinaries.DirPath;\n        public string DeploymentId => txt_DeploymentId.Text;\n    }\n}\n"
  },
  {
    "path": "Samples/YamsStudio/AddNewDeploymentDialog.xaml",
    "content": "﻿<Window x:Class=\"YamsStudio.AddNewDeploymentDialog\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n        xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n        xmlns:controls=\"clr-namespace:YamsStudio\"\n        xmlns:local=\"clr-namespace:YamsStudio\"\n        mc:Ignorable=\"d\"\n        Title=\"Add New Application\" SizeToContent=\"WidthAndHeight\" WindowStartupLocation=\"CenterOwner\"\n        ContentRendered=\"Window_ContentRendered\">\n    <Grid Margin=\"15\">\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"Auto\" />\n            <ColumnDefinition Width=\"*\" />\n        </Grid.ColumnDefinitions>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n        </Grid.RowDefinitions>\n        <StackPanel>\n            <Label x:Name=\"lbl_ApplicationName\" Content=\"Name:\"/>\n            <TextBox x:Name=\"txt_AplicationName\" MinWidth=\"250\" IsReadOnly=\"True\"/>\n            <Label x:Name=\"lbl_Version\" Content=\"Version:\"/>\n            <TextBox x:Name=\"txt_Version\" MinWidth=\"250\" IsReadOnly=\"True\"/>\n            <Label x:Name=\"lbl_DeploymentId\" Content=\"DeploymentId:\"/>\n            <TextBox x:Name=\"txt_DeploymentId\" Grid.Row=\"1\" MinWidth=\"250\"/>            \n        </StackPanel>\n\n        <WrapPanel Grid.Row=\"2\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Right\" Margin=\"0,15,0,0\">\n            <Button IsDefault=\"True\" Name=\"btn_DialogOk\" Click=\"OnOk\" MinWidth=\"60\" Margin=\"0,0,10,0\">_Ok</Button>\n            <Button IsCancel=\"True\" MinWidth=\"60\">_Cancel</Button>\n        </WrapPanel>\n    </Grid>\n</Window>\n"
  },
  {
    "path": "Samples/YamsStudio/AddNewDeploymentDialog.xaml.cs",
    "content": "﻿using System;\nusing System.Windows;\n\nnamespace YamsStudio\n{\n    /// <summary>\n    /// Interaction logic for AddNewDeploymentDialog.xaml\n    /// </summary>\n    public partial class AddNewDeploymentDialog : Window\n    {\n        public AddNewDeploymentDialog(string appId, string version)\n        {\n            InitializeComponent();\n\n            txt_AplicationName.Text = appId;\n            txt_Version.Text = version;\n        }\n\n        private void Window_ContentRendered(object sender, EventArgs e)\n        {\n            txt_DeploymentId.SelectAll();\n            txt_DeploymentId.Focus();\n        }\n\n        private void OnOk(object sender, RoutedEventArgs e)\n        {\n            this.DialogResult = true;\n        }\n\n        public string DeploymentId => txt_DeploymentId.Text;\n    }\n}\n"
  },
  {
    "path": "Samples/YamsStudio/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.6.1\" />\n    </startup>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.Practices.ServiceLocation\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-1.3.0.0\" newVersion=\"1.3.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>\n"
  },
  {
    "path": "Samples/YamsStudio/App.xaml",
    "content": "﻿<Application x:Class=\"YamsStudio.App\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:local=\"clr-namespace:YamsStudio\"\n             StartupUri=\"MainWindow.xaml\">\n    <Application.Resources>\n         \n    </Application.Resources>\n</Application>\n"
  },
  {
    "path": "Samples/YamsStudio/App.xaml.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Configuration;\nusing System.Data;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\n\nnamespace YamsStudio\n{\n    /// <summary>\n    /// Interaction logic for App.xaml\n    /// </summary>\n    public partial class App : Application\n    {\n    }\n}\n"
  },
  {
    "path": "Samples/YamsStudio/BusyWindow.xaml",
    "content": "﻿<Window x:Class=\"YamsStudio.BusyWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n        xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n        xmlns:local=\"clr-namespace:YamsStudio\"\n        mc:Ignorable=\"d\"\n        Title=\"BusyWindow\" SizeToContent=\"WidthAndHeight\" WindowStartupLocation=\"CenterOwner\">\n    <Grid>\n        <Label x:Name=\"lbl_message\"></Label>\n    </Grid>\n</Window>\n"
  },
  {
    "path": "Samples/YamsStudio/BusyWindow.xaml.cs",
    "content": "﻿using System.Windows;\n\nnamespace YamsStudio\n{\n    /// <summary>\n    /// Interaction logic for BusyWindow.xaml\n    /// </summary>\n    public partial class BusyWindow : Window\n    {\n        public BusyWindow()\n        {\n            InitializeComponent();\n        }\n\n        public string Message\n        {\n            get\n            {\n                return lbl_message.Content.ToString();\n            }\n            set\n            {\n                lbl_message.Content = value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/YamsStudio/ConnectToStorageAccountDialog.xaml",
    "content": "﻿<Window x:Class=\"YamsStudio.ConnectToStorageAccountDialog \"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n        xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n        xmlns:local=\"clr-namespace:YamsStudio\"\n        mc:Ignorable=\"d\"\n        Title=\"Connection Setup\" SizeToContent=\"WidthAndHeight\" WindowStartupLocation=\"CenterOwner\"\n        ContentRendered=\"Window_ContentRendered\">\n    <Grid Margin=\"15\">\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"Auto\" />\n            <ColumnDefinition Width=\"*\" />\n        </Grid.ColumnDefinitions>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n        </Grid.RowDefinitions>\n\n        <StackPanel>\n            <Label Name=\"lbl_AccountName\" Grid.Column=\"1\">Account Name:</Label>\n            <TextBox Name=\"txt_AccountName\" Grid.Column=\"1\" Grid.Row=\"1\" MinWidth=\"250\"></TextBox>\n            <Label Name=\"lbl_DataConnectionString\" Grid.Column=\"1\">Data Connection String:</Label>\n            <TextBox Name=\"txt_DataConnectionString\" Grid.Column=\"1\" Grid.Row=\"1\" MinWidth=\"250\"></TextBox>\n        </StackPanel>\n\n        <WrapPanel Grid.Row=\"2\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Right\" Margin=\"0,15,0,0\">\n            <Button IsDefault=\"True\" Name=\"btn_DialogOk\" Click=\"OnOk\" MinWidth=\"60\" Margin=\"0,0,10,0\">_Ok</Button>\n            <Button IsCancel=\"True\" MinWidth=\"60\">_Cancel</Button>\n        </WrapPanel>\n    </Grid>\n</Window>\n"
  },
  {
    "path": "Samples/YamsStudio/ConnectToStorageAccountDialog.xaml.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Shapes;\n\nnamespace YamsStudio\n{\n    /// <summary>\n    /// Interaction logic for ConnectToStorageAccountDialog.xaml\n    /// </summary>\n    public partial class ConnectToStorageAccountDialog : Window\n    {\n        public ConnectToStorageAccountDialog()\n        {\n            InitializeComponent();\n        }\n\n        private void OnOk(object sender, RoutedEventArgs e)\n        {\n            this.DialogResult = true;\n        }\n\n        private void Window_ContentRendered(object sender, EventArgs e)\n        {\n            txt_AccountName.SelectAll();\n            txt_AccountName.Focus();\n        }\n\n        public string AccountName => txt_AccountName.Text;\n        public string DataConnectionString => txt_DataConnectionString.Text;\n    }\n}\n"
  },
  {
    "path": "Samples/YamsStudio/DeploymentInfo.cs",
    "content": "﻿using Etg.Yams.Application;\n\nnamespace YamsStudio\n{\n    public class DeploymentInfo\n    {\n\t    public DeploymentInfo(AppIdentity appIdentity, string deploymentId)\n        {\n            AppIdentity = appIdentity;\n            DeploymentId = deploymentId;\n        }\n\n        public AppIdentity AppIdentity { get; }\n\n\t    public string DeploymentId { get; }\n    }\n}"
  },
  {
    "path": "Samples/YamsStudio/DeploymentRepositoryFactory.cs",
    "content": "﻿// -------------------------------------------------------------------\n// Copyright (c) Microsoft Corporation. All Rights Reserved.\n// -------------------------------------------------------------------\n\nusing Etg.Yams.Azure.Storage;\nusing Etg.Yams.Json;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Config;\nusing Newtonsoft.Json.Serialization;\n\nnamespace YamsStudio\n{\n    public class DeploymentRepositoryFactory : IDeploymentRepositoryFactory\n    {\n        public IDeploymentRepository CreateRepository(string connectionString)\n        {\n            return new BlobStorageDeploymentRepository(connectionString, new JsonDeploymentConfigSerializer(\n                new JsonSerializer(new DiagnosticsTraceWriter())));\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/YamsStudio/DeploymentRepositoryManager.cs",
    "content": "﻿using System.Collections.Generic;\nusing Etg.Yams.Storage;\n\nnamespace YamsStudio\n{\n    public class DeploymentRepositoryManager\n    {\n        private readonly IDeploymentRepositoryFactory _connectionFactory;\n        private readonly Dictionary<string, IDeploymentRepository> _repos \n            = new Dictionary<string, IDeploymentRepository>();\n        public DeploymentRepositoryManager(IDeploymentRepositoryFactory connectionFactory)\n        {\n            _connectionFactory = connectionFactory;\n        }\n\n        public IDeploymentRepository GetRepository(StorageAccountConnectionInfo connectionInfo)\n        {\n            string connectionString = connectionInfo.ConnectionString;\n            if (!_repos.ContainsKey(connectionString))\n            {\n                IDeploymentRepository repository = _connectionFactory.CreateRepository(connectionInfo.ConnectionString);\n                _repos.Add(connectionString, repository);\n            }\n\n            return _repos[connectionString];\n        }\n    }\n}"
  },
  {
    "path": "Samples/YamsStudio/IDeploymentRepositoryFactory.cs",
    "content": "﻿using Etg.Yams.Storage;\n\nnamespace YamsStudio\n{\n    public interface IDeploymentRepositoryFactory\n    {\n        IDeploymentRepository CreateRepository(string connectionString);\n    }\n}"
  },
  {
    "path": "Samples/YamsStudio/MainWindow.xaml",
    "content": "﻿<Window x:Class=\"YamsStudio.MainWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n        xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n        xmlns:local=\"clr-namespace:YamsStudio\"\n        mc:Ignorable=\"d\"\n        Title=\"YAMS Studio\" Height=\"350\" Width=\"525\">\n    <ScrollViewer>\n        <DockPanel>\n            <StackPanel DockPanel.Dock=\"Top\" x:Name=\"ActionsPanel\" HorizontalAlignment=\"Stretch\" VerticalAlignment=\"Top\">\n                <Button x:Name=\"AddConnectionButton\" Content=\"Add New Connection\" Click=\"OnAddNewConnection\" Width=\"120\" HorizontalAlignment=\"Left\"></Button>\n            </StackPanel>\n            <StackPanel Orientation=\"Horizontal\">\n                <ListView x:Name=\"ConnectionsListView\" Margin=\"5\" SelectionMode=\"Single\" SelectionChanged=\"OnConnectionSelected\" Background=\"{x:Null}\">\n                    <ListView.View>\n                        <GridView>\n                            <GridViewColumn Header=\"Connections\" DisplayMemberBinding=\"{Binding AccountName}\" />\n                        </GridView>\n                    </ListView.View>\n                    <ListView.ItemContainerStyle>\n                        <Style TargetType=\"ListViewItem\">\n                            <Setter Property=\"ContextMenu\">\n                                <Setter.Value>\n                                    <ContextMenu>\n                                        <MenuItem Header=\"Add Application\">\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnAddApplication\"/>\n                                                </Style>\n                                            </MenuItem.Style>\n                                        </MenuItem>\n                                        <MenuItem Header=\"Publish to blob\">\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnPublishToBlob\"/>\n                                                </Style>\n                                            </MenuItem.Style>                                              \n                                        </MenuItem>  \n                                        <MenuItem Header=\"Sync from blob\">\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnSyncFromBlob\"/>\n                                                </Style>\n                                            </MenuItem.Style>                                              \n                                        </MenuItem>      \n                                        <MenuItem Header=\"Delete Connection\" >\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnDeleteConnection\"/>\n                                                </Style>\n                                            </MenuItem.Style>\n                                        </MenuItem>  \n                                        <MenuItem Header=\"Edit DeploymentConfig.json\" >\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnEditDeploymentConfig\"/>\n                                                </Style>\n                                            </MenuItem.Style>\n                                        </MenuItem>                                          \n                                    </ContextMenu>\n                                </Setter.Value>\n                            </Setter>\n                        </Style>\n                    </ListView.ItemContainerStyle>\n                </ListView>\n                <ListView x:Name=\"AppsListView\" Margin=\"5\" SelectionMode=\"Single\" SelectionChanged=\"OnAppSelected\">\n                    <ListView.View>\n                        <GridView>\n                            <GridViewColumn Header=\"Applications\" />\n                        </GridView>\n                    </ListView.View>\n                    <ListView.ItemContainerStyle>\n                        <Style TargetType=\"ListViewItem\">\n                            <Setter Property=\"ContextMenu\">\n                                <Setter.Value>\n                                    <ContextMenu>\n                                        <MenuItem Header=\"Add new version\">\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnAddNewVersion\"/>\n                                                </Style>\n                                            </MenuItem.Style>                                              \n                                        </MenuItem>\n                                        <MenuItem Header=\"Remove Application\">\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnRemoveApplication\"/>\n                                                </Style>\n                                            </MenuItem.Style>\n                                        </MenuItem>\n                                    </ContextMenu>\n                                </Setter.Value>\n                            </Setter>\n                        </Style>\n                    </ListView.ItemContainerStyle>                    \n                </ListView>\n                <ListView x:Name=\"VersionsListView\" Margin=\"5\" SelectionMode=\"Single\"  SelectionChanged=\"OnVersionSelected\">\n                    <ListView.View>\n                        <GridView>\n                            <GridViewColumn Header=\"Versions\" DisplayMemberBinding=\"{Binding Version}\" />\n                        </GridView>\n                    </ListView.View>\n                    <ListView.ItemContainerStyle>\n                        <Style TargetType=\"ListViewItem\">\n                            <Setter Property=\"ContextMenu\">\n                                <Setter.Value>\n                                    <ContextMenu>\n                                        <MenuItem Header=\"Add Deployment\">\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnVersionAddDeployment\"/>\n                                                </Style>\n                                            </MenuItem.Style>                                              \n                                        </MenuItem>                                        \n                                        <MenuItem Header=\"Upgrade/Downgrade\">\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnUpdateVersion\"/>\n                                                </Style>\n                                            </MenuItem.Style>                                              \n                                        </MenuItem>\n                                        <MenuItem Header=\"Remove Version\">\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnRemoveVersion\"/>\n                                                </Style>\n                                            </MenuItem.Style>\n                                        </MenuItem>\n                                    </ContextMenu>\n                                </Setter.Value>\n                            </Setter>\n                        </Style>\n                    </ListView.ItemContainerStyle>                      \n                </ListView>\n                <ListView x:Name=\"deploymentIdsListView\" Margin=\"5\" SelectionMode=\"Single\">\n                    <ListView.View>\n                        <GridView>\n                            <GridViewColumn Header=\"DeploymentIds\" DisplayMemberBinding=\"{Binding DeploymentId}\" />\n                        </GridView>\n                    </ListView.View>\n                    <ListView.ItemContainerStyle>\n                        <Style TargetType=\"ListViewItem\">\n                            <Setter Property=\"ContextMenu\">\n                                <Setter.Value>\n                                    <ContextMenu>\n                                        <MenuItem Header=\"Remove Deployment\">\n                                            <MenuItem.Style>\n                                                <Style TargetType=\"MenuItem\">\n                                                    <EventSetter Event=\"Click\" Handler=\"OnRemoveDeployment\"/>\n                                                </Style>\n                                            </MenuItem.Style>\n                                        </MenuItem>\n                                    </ContextMenu>\n                                </Setter.Value>\n                            </Setter>\n                        </Style>\n                    </ListView.ItemContainerStyle>   \n                </ListView>\n            </StackPanel>\n        </DockPanel>\n    </ScrollViewer>\n</Window>\n"
  },
  {
    "path": "Samples/YamsStudio/MainWindow.xaml.cs",
    "content": "﻿using Etg.Yams.Application;\nusing Microsoft.WindowsAzure.Storage;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing Etg.Yams.Json;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Utils;\nusing Newtonsoft.Json.Serialization;\nusing Semver;\n\nnamespace YamsStudio\n{\n    /// <summary>\n    /// Interaction logic for MainWindow.xaml\n    /// </summary>\n    public partial class MainWindow : Window\n    {\n        private const string SettingsFilePath = \"settings.json\";\n        private const string DeploymentsConfigsDirPath = \"DeploymentsConfigs\";\n        private readonly List<StorageAccountConnectionInfo> _storageAccountConnections = new List<StorageAccountConnectionInfo>();\n        private readonly DeploymentRepositoryManager _deploymentRepositoryManager;\n        private DeploymentConfig _deploymentConfig;\n        private readonly FileSystemWatcher _deploymentConfigFileWatcher;\n        private readonly IJsonSerializer _jsonSerializer;\n        private readonly IDeploymentConfigSerializer _deploymentConfigSerializer;\n\n        public MainWindow()\n        {\n            InitializeComponent();\n            ConnectionsListView.ItemsSource = _storageAccountConnections;\n            IDeploymentRepositoryFactory deploymentRepositoryFactory = new DeploymentRepositoryFactory();\n            _deploymentRepositoryManager = new DeploymentRepositoryManager(deploymentRepositoryFactory);\n            _jsonSerializer = new JsonSerializer(new DiagnosticsTraceWriter());\n            _deploymentConfigSerializer = new JsonDeploymentConfigSerializer(_jsonSerializer);\n            if (File.Exists(SettingsFilePath))\n            {\n                string json = File.ReadAllText(SettingsFilePath);\n                _storageAccountConnections = _jsonSerializer.Deserialize<List<StorageAccountConnectionInfo>>(json);\n                ConnectionsListView.ItemsSource = _storageAccountConnections;\n            }\n\n            if (!Directory.Exists(DeploymentsConfigsDirPath))\n            {\n                Directory.CreateDirectory(DeploymentsConfigsDirPath);\n            }\n\n\t        _deploymentConfigFileWatcher = new FileSystemWatcher\n\t        {\n\t\t        Path = Path.GetFullPath(DeploymentsConfigsDirPath),\n\t\t        NotifyFilter = NotifyFilters.LastWrite,\n\t\t        Filter = \"*.json\"\n\t        };\n\t        _deploymentConfigFileWatcher.Changed += OnDeploymentConfigFileChanged;\n            _deploymentConfigFileWatcher.EnableRaisingEvents = true;\n        }\n\n        protected override void OnClosing(CancelEventArgs e)\n        {\n            string json = _jsonSerializer.Serialize(_storageAccountConnections);\n            File.WriteAllText(SettingsFilePath, json);\n            _deploymentConfigFileWatcher.Dispose();\n            base.OnClosing(e);\n        }\n\n        private void OnAddNewConnection(object sender, RoutedEventArgs e)\n        {\n            ConnectToStorageAccountDialog inputDialog = new ConnectToStorageAccountDialog();\n            if (inputDialog.ShowDialog() == true)\n            {\n                StorageAccountConnectionInfo connection = new StorageAccountConnectionInfo(inputDialog.AccountName, inputDialog.DataConnectionString);\n                _storageAccountConnections.Add(connection);\n                RefreshView(_storageAccountConnections);\n            }\n        }\n\n        private void OnDeleteConnection(object sender, RoutedEventArgs e)\n        {\n            StorageAccountConnectionInfo connectionInfo = (StorageAccountConnectionInfo)ConnectionsListView.SelectedItem;\n            MessageBoxResult res = MessageBox.Show(\"The connection will be removed\\n Do you want to continue\", \"Remove Connection\", MessageBoxButton.YesNo);\n            if (res == MessageBoxResult.Yes)\n            {\n                _storageAccountConnections.Remove(connectionInfo);\n                RefreshView(_storageAccountConnections);\n            }\n        }\n\n        private async void OnAddApplication(object sender, RoutedEventArgs e)\n        {\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            AddNewApplicationDialog dialog = new AddNewApplicationDialog();\n            if (dialog.ShowDialog() == true)\n            {\n                AppIdentity appIdentity = new AppIdentity(dialog.ApplicationName, SemVersion.Parse(dialog.Version));\n                await AddApplication(appIdentity, dialog.DeploymentId, dialog.BinariesPath);\n            }\n        }\n\n        private async Task AddApplication(AppIdentity appIdentity, string deploymentId, string binariesPath)\n        {\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            IDeploymentRepository repository = _deploymentRepositoryManager.GetRepository(connectionInfo);\n            BusyWindow busyWindow = new BusyWindow{Message = \"Please wait..\\n\\n\" + \"The binaries are being uploaded to blob storage\"};\n            busyWindow.Show();\n            await repository.UploadApplicationBinaries(appIdentity, binariesPath, ConflictResolutionMode.DoNothingIfBinariesExist);\n            busyWindow.Close();\n            _deploymentConfig = _deploymentConfig.AddApplication(appIdentity, deploymentId);\n            SaveLocalDeploymentConfig(connectionInfo);\n        }\n\n        private async Task RefreshAll()\n        {\n            await HandleConnectionSelection();\n            HandleAppSelection();\n            HandleVersionSelection();\n        }\n\n        private void SaveLocalDeploymentConfig(StorageAccountConnectionInfo connectionInfo)\n        {\n            string json = _deploymentConfigSerializer.Serialize(_deploymentConfig);\n            SaveLocalDeploymentConfig(connectionInfo, json);\n        }\n\n        private void SaveLocalDeploymentConfig(StorageAccountConnectionInfo connectionInfo, string json)\n        {\n            string localDeploymentConfigPath = GetDeploymentConfigLocalPath(connectionInfo.AccountName);\n            File.WriteAllText(localDeploymentConfigPath, json);\n        }\n\n        private StorageAccountConnectionInfo GetCurrentConnection()\n        {\n            return (StorageAccountConnectionInfo)ConnectionsListView.SelectedItem;\n        }\n\n        private async void OnRemoveApplication(object sender, RoutedEventArgs e)\n        {\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            string appId = GetSelectedAppId();\n\t\t\t_deploymentConfig = _deploymentConfig.RemoveApplication(appId);\n            SaveLocalDeploymentConfig(connectionInfo);\n            await HandleConnectionSelection();\n        }\n\n        private async void OnAddNewVersion(object sender, RoutedEventArgs e)\n        {\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            string appId = GetSelectedAppId();\n            AddNewApplicationDialog dialog = new AddNewApplicationDialog(appId);\n            if (dialog.ShowDialog() == true)\n            {\n                AppIdentity appIdentity = new AppIdentity(dialog.ApplicationName, SemVersion.Parse(dialog.Version));\n                await AddApplication(appIdentity, dialog.DeploymentId, dialog.BinariesPath);\n            }\n        }\n\n        private void OnVersionAddDeployment(object sender, RoutedEventArgs e)\n        {\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            string appId = GetSelectedAppId();\n            string version = GetSelectedVersion();\n            AddNewDeploymentDialog dialog = new AddNewDeploymentDialog(appId, version);\n            if (dialog.ShowDialog() == true)\n            {\n                AppIdentity appIdentity = new AppIdentity(appId, SemVersion.Parse(version));\n                _deploymentConfig = _deploymentConfig.AddApplication(appIdentity, dialog.DeploymentId);\n                SaveLocalDeploymentConfig(connectionInfo);\n            }\n        }\n\n        private async void OnUpdateVersion(object sender, RoutedEventArgs e)\n        {\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            string appId = GetSelectedAppId();\n            string version = GetSelectedVersion();\n\t        AppIdentity appIdentity = new AppIdentity(appId, version);\n\t\t\tIEnumerable<string> availableDeploymentIds = _deploymentConfig.ListClusters(appIdentity);\n            UpdateVersionDialog dialog = new UpdateVersionDialog(appId, version, availableDeploymentIds);\n            if (dialog.ShowDialog() == true)\n            {\n                string newVersion = dialog.NewVersion;\n                AppIdentity newAppIdentity = new AppIdentity(appIdentity.Id, newVersion);\n                IEnumerable<string> selectedDeploymentIds = dialog.SelectedDeploymentIds;\n                foreach (string deploymentId in selectedDeploymentIds)\n                {\n                    await AddApplication(newAppIdentity, deploymentId, dialog.BinariesPath);\n                    _deploymentConfig = _deploymentConfig.RemoveApplication(appIdentity, deploymentId);\n                }\n\n                SaveLocalDeploymentConfig(connectionInfo);\n            }\n        }\n\n        private void OnRemoveVersion(object sender, RoutedEventArgs e)\n        {\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            string appId = GetSelectedAppId();\n            if (appId == null)\n            {\n                return;\n            }\n\n            string version = GetSelectedVersion();\n            if (version == null)\n            {\n                return;\n            }\n\n\t\t\t_deploymentConfig = _deploymentConfig.RemoveApplication(new AppIdentity(appId, version));\n            SaveLocalDeploymentConfig(connectionInfo);\n        }\n\n        private void OnRemoveDeployment(object sender, RoutedEventArgs e)\n        {\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            DeploymentInfo deploymendInfo = deploymentIdsListView.SelectedItem as DeploymentInfo;\n            if (deploymendInfo == null)\n            {\n                return;\n            }\n\n\t\t\t_deploymentConfig = _deploymentConfig.RemoveApplication(deploymendInfo.AppIdentity, deploymendInfo.DeploymentId);\n            SaveLocalDeploymentConfig(connectionInfo);\n        }\n\n        private string GetSelectedVersion()\n        {\n            return ((AppIdentity)VersionsListView.SelectedItem)?.Version.ToString();\n        }\n\n        private async void OnPublishToBlob(object sender, RoutedEventArgs e)\n        {\n            BusyWindow busyWindow = new BusyWindow{Message = \"Please wait..\\n\\n\" + \"The DeploymentConfig.json file is being uploaded to blob storage\"};\n            busyWindow.Show();\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            IDeploymentRepository connection = _deploymentRepositoryManager.GetRepository(connectionInfo);\n            await connection.PublishDeploymentConfig(_deploymentConfig);\n            busyWindow.Close();\n        }\n\n        private async void OnSyncFromBlob(object sender, RoutedEventArgs e)\n        {\n            MessageBoxResult res = MessageBox.Show(\"This will ovewrite any local changes\\n\\n Are you sure you want to continue?\",\n                \"Sync From Blob\", MessageBoxButton.YesNo);\n            if (res == MessageBoxResult.Yes)\n            {\n                StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n                IDeploymentRepository connection = _deploymentRepositoryManager.GetRepository(connectionInfo);\n                DeploymentConfig deploymentConfig = await connection.FetchDeploymentConfig();\n                SaveLocalDeploymentConfig(connectionInfo, _deploymentConfigSerializer.Serialize(deploymentConfig));\n            }\n        }\n\n        private void OnEditDeploymentConfig(object sender, RoutedEventArgs e)\n        {\n\t        string path = GetDeploymentConfigLocalPath(GetCurrentConnection().AccountName);\n\t\t\tProcess.Start(path);\n        }\n\n        private void RefreshView(object itemsSource)\n        {\n            ICollectionView view = CollectionViewSource.GetDefaultView(itemsSource);\n            view.Refresh();\n        }\n\n        private async void OnConnectionSelected(object sender, SelectionChangedEventArgs e)\n        {\n            if (e.AddedItems.Count > 0)\n            {\n                await HandleConnectionSelection();\n            }\n        }\n\n        private async Task HandleConnectionSelection()\n        {\n            StorageAccountConnectionInfo connectionInfo = GetCurrentConnection();\n            IEnumerable<string> appIds = new List<string>();\n            try\n            {\n                _deploymentConfig = await FetchDeploymentConfig(connectionInfo);\n\t\t\t\tappIds = _deploymentConfig.ListApplications();\n            }\n            catch (StorageException ex)\n            {\n                Debug.WriteLine(\"Failed to fetch the DeploymentConfig file from account \" + connectionInfo.AccountName + \" Exception: \" + ex);\n            }\n\n            AppsListView.ItemsSource = appIds;\n            RefreshView(appIds);\n        }\n\n        private async void OnDeploymentConfigFileChanged(object sender, FileSystemEventArgs e)\n        {\n            await Dispatcher.Invoke(RefreshAll);\n        }\n\n        private async Task<DeploymentConfig> FetchDeploymentConfig(StorageAccountConnectionInfo connectionInfo)\n        {\n            string path = GetDeploymentConfigLocalPath(connectionInfo.AccountName);\n            if (File.Exists(path))\n            {\n                return _deploymentConfigSerializer.Deserialize(File.ReadAllText(path));\n            }\n\t        IDeploymentRepository connection = _deploymentRepositoryManager.GetRepository(connectionInfo);\n\t        DeploymentConfig deploymentConfig = await connection.FetchDeploymentConfig();\n\t\t\tSaveLocalDeploymentConfig(connectionInfo, _deploymentConfigSerializer.Serialize(deploymentConfig));\n\t        return deploymentConfig;\n        }\n\n        private string GetDeploymentConfigLocalPath(string accountName)\n        {\n            return Path.Combine(DeploymentsConfigsDirPath + Path.DirectorySeparatorChar, accountName + \"_DeploymentConfig.json\");\n        }\n\n        private void OnAppSelected(object sender, SelectionChangedEventArgs e)\n        {\n            HandleAppSelection();\n        }\n\n        private void HandleAppSelection()\n        {\n            string id = GetSelectedAppId();\n            IEnumerable<AppIdentity> apps;\n            if (id != null)\n            {\n                apps = _deploymentConfig.ListVersions(id).Select(v => new AppIdentity(id, SemVersion.Parse(v)));\n            }\n            else\n            {\n                apps = new List<AppIdentity>();\n            }\n\n            VersionsListView.ItemsSource = apps;\n            RefreshView(apps);\n        }\n\n        private string GetSelectedAppId()\n        {\n            return (string)AppsListView.SelectedItem;\n        }\n\n        private void OnVersionSelected(object sender, SelectionChangedEventArgs e)\n        {\n            HandleVersionSelection();\n        }\n\n        private void HandleVersionSelection()\n        {\n            AppIdentity appIdentity = VersionsListView.SelectedItem as AppIdentity;\n            IEnumerable<DeploymentInfo> deployments;\n            if (appIdentity != null)\n            {\n                deployments = _deploymentConfig.ListClusters(appIdentity).Select(deploymentId => new DeploymentInfo(appIdentity, deploymentId));\n            }\n            else\n            {\n                deployments = new List<DeploymentInfo>();\n            }\n\n            deploymentIdsListView.ItemsSource = deployments;\n            RefreshView(deployments);\n        }\n    }\n}"
  },
  {
    "path": "Samples/YamsStudio/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Windows;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"YamsStudio\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"YamsStudio\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2015\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n//In order to begin building localizable applications, set \n//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file\n//inside a <PropertyGroup>.  For example, if you are using US english\n//in your source files, set the <UICulture> to en-US.  Then uncomment\n//the NeutralResourceLanguage attribute below.  Update the \"en-US\" in\n//the line below to match the UICulture setting in the project file.\n\n//[assembly: NeutralResourcesLanguage(\"en-US\", UltimateResourceFallbackLocation.Satellite)]\n\n\n[assembly: ThemeInfo(\n    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located\n                                     //(used if a resource is not found in the page, \n                                     // or application resource dictionaries)\n    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located\n                                              //(used if a resource is not found in the page, \n                                              // app, or any theme specific resource dictionaries)\n)]\n\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Samples/YamsStudio/Properties/Resources.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 YamsStudio.Properties {\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\", \"4.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\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 Resources() {\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(\"YamsStudio.Properties.Resources\", typeof(Resources).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}\n"
  },
  {
    "path": "Samples/YamsStudio/Properties/Resources.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.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: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\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\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\" 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: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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Samples/YamsStudio/Properties/Settings.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 YamsStudio.Properties {\n    \n    \n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator\", \"14.0.0.0\")]\n    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {\n        \n        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));\n        \n        public static Settings Default {\n            get {\n                return defaultInstance;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/YamsStudio/Properties/Settings.settings",
    "content": "﻿<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"uri:settings\" CurrentProfile=\"(Default)\">\n  <Profiles>\n    <Profile Name=\"(Default)\" />\n  </Profiles>\n  <Settings />\n</SettingsFile>"
  },
  {
    "path": "Samples/YamsStudio/SelectDirectoryControl.xaml",
    "content": "﻿<UserControl x:Class=\"YamsStudio.SelectDirectoryControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             xmlns:local=\"clr-namespace:YamsStudio\"\n             mc:Ignorable=\"d\" >\n    <Grid>\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"*\"></ColumnDefinition>\n            <ColumnDefinition Width=\"Auto\"></ColumnDefinition>\n        </Grid.ColumnDefinitions>\n            <TextBox x:Name=\"txt_DirPath\" HorizontalAlignment=\"Stretch\"/>\n            <Button Click=\"OnBrowse\" HorizontalAlignment=\"Right\" Width=\"42\" Content=\"browse\"/>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Samples/YamsStudio/SelectDirectoryControl.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Forms;\n\nnamespace YamsStudio\n{\n    /// <summary>\n    /// Interaction logic for SelectDirectoryControl.xaml\n    /// </summary>\n    public partial class SelectDirectoryControl : System.Windows.Controls.UserControl\n    {\n\t    private static string _selectedPath;\n\n        public SelectDirectoryControl()\n        {\n            InitializeComponent();\n        }\n\n        private void OnBrowse(object sender, RoutedEventArgs e)\n        {\n            FolderBrowserDialog dialog = new FolderBrowserDialog();\n\t        dialog.SelectedPath = _selectedPath;\n\t\t\tif (dialog.ShowDialog() == DialogResult.OK)\n            {\n                _selectedPath = dialog.SelectedPath;\n                txt_DirPath.Text = _selectedPath;\n            }\n        }\n\n        public string DirPath => txt_DirPath.Text;\n    }\n}\n"
  },
  {
    "path": "Samples/YamsStudio/StorageAccountConnectionInfo.cs",
    "content": "﻿namespace YamsStudio\n{\n    public class StorageAccountConnectionInfo\n    {\n\t    public StorageAccountConnectionInfo(string accountName, string connectionString)\n        {\n            AccountName = accountName;\n            ConnectionString = connectionString;\n        }\n\n        public string AccountName { get; }\n\n\t    public string ConnectionString { get; }\n    }\n}"
  },
  {
    "path": "Samples/YamsStudio/UpdateVersionDialog.xaml",
    "content": "﻿<Window x:Class=\"YamsStudio.UpdateVersionDialog\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n        xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n        xmlns:local=\"clr-namespace:YamsStudio\"\n        xmlns:controls=\"clr-namespace:YamsStudio\"\n        mc:Ignorable=\"d\"\n        Title=\"Updgrade/Downgrade Version\" SizeToContent=\"WidthAndHeight\" WindowStartupLocation=\"CenterOwner\"\n        ContentRendered=\"Window_ContentRendered\" >\n    <Grid Margin=\"15\">\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"Auto\" />\n            <ColumnDefinition Width=\"*\" />\n        </Grid.ColumnDefinitions>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n        </Grid.RowDefinitions>\n        <Label Grid.Row=\"0\" Grid.Column=\"0\" x:Name=\"lbl_ApplicationName\" Content=\"Application Name:\"/>\n        <TextBox Grid.Row=\"0\" Grid.Column=\"1\" x:Name=\"txt_AplicationName\" IsReadOnly=\"True\"/>\n        <Label Grid.Row=\"1\" Grid.Column=\"0\" x:Name=\"lbl_CurrentVersion\" Content=\"Current Version:\"/>\n        <TextBox Grid.Column=\"1\" Grid.Row=\"1\" x:Name=\"txt_CurrentVersion\" IsReadOnly=\"True\"/>\n        <Label Grid.Row=\"2\" Grid.Column=\"0\" x:Name=\"lbl_NewVersion\" Content=\"New Version:\"/>\n        <TextBox Grid.Column=\"1\" Grid.Row=\"2\" x:Name=\"txt_NewVersion\"/>\n        <Label Grid.Row=\"3\" Grid.Column=\"0\" x:Name=\"lbl_DeploymentIds\" Content=\"DeploymentIds\"></Label>\n        <ListView Grid.Row=\"3\" Grid.Column=\"1\" x:Name=\"lv_DeploymentIds\"></ListView>\n        <Label Grid.Row=\"4\" Grid.Column=\"0\" Content=\"Binaries Path\"></Label>\n        <controls:SelectDirectoryControl x:Name=\"uc_SelectBinaries\" Grid.Row=\"4\" Grid.Column=\"1\" HorizontalAlignment=\"Stretch\" HorizontalContentAlignment=\"Stretch\"></controls:SelectDirectoryControl>\n        <WrapPanel Grid.Row=\"5\" Grid.Column=\"1\" HorizontalAlignment=\"Right\">\n            <Button IsDefault=\"True\" Name=\"btn_DialogOk\" Click=\"OnOk\" MinWidth=\"60\" Margin=\"0,0,10,0\">_Ok</Button>\n            <Button IsCancel=\"True\" MinWidth=\"60\">_Cancel</Button>\n        </WrapPanel>\n    </Grid>\n</Window>\n"
  },
  {
    "path": "Samples/YamsStudio/UpdateVersionDialog.xaml.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Windows;\n\nnamespace YamsStudio\n{\n    /// <summary>\n    /// Interaction logic for UpdateVersionDialog.xaml\n    /// </summary>\n    public partial class UpdateVersionDialog : Window\n    {\n        public UpdateVersionDialog(string appName, string currentVersion, IEnumerable<string> deploymentIds)\n        {\n            InitializeComponent();\n\n            txt_AplicationName.Text = appName;\n            txt_CurrentVersion.Text = currentVersion;\n            foreach(string deploymentId in deploymentIds)\n            {\n                lv_DeploymentIds.Items.Add(deploymentId);\n            }\n        }\n\n        private void Window_ContentRendered(object sender, EventArgs e)\n        {\n            txt_NewVersion.SelectAll();\n            txt_NewVersion.Focus();\n            lv_DeploymentIds.SelectAll();\n        }\n\n        public string NewVersion => txt_NewVersion.Text;\n\n        public IEnumerable<string> SelectedDeploymentIds\n        {\n            get\n            {\n                List<string> selectedItems = new List<string>();\n                foreach(object obj in lv_DeploymentIds.SelectedItems)\n                {\n                    selectedItems.Add((string)obj);\n                }\n                return selectedItems;\n            }\n        }\n\n        public string BinariesPath => uc_SelectBinaries.DirPath;\n\n        private void OnOk(object sender, RoutedEventArgs e)\n        {\n            DialogResult = true;\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/YamsStudio/YamsStudio.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{41BD41B6-362E-4924-B801-7C2138A55BFF}</ProjectGuid>\n    <OutputType>WinExe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>YamsStudio</RootNamespace>\n    <AssemblyName>YamsStudio</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n    <WarningLevel>4</WarningLevel>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.1.0-rc\\lib\\net451\\Etg.Yams.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.AzureBlobStorageDeploymentRepository, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.1.0-rc\\lib\\net451\\Etg.Yams.AzureBlobStorageDeploymentRepository.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.AzureBlobStorageUpdateSession, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.1.0-rc\\lib\\net451\\Etg.Yams.AzureBlobStorageUpdateSession.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.AzureUtils, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.1.0-rc\\lib\\net451\\Etg.Yams.AzureUtils.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.1.0-rc\\lib\\net451\\Etg.Yams.Common.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.Yams.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Etg.Yams.1.1.0-rc\\lib\\net451\\Etg.Yams.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.6.4\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.OData.5.6.4\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.Data.Services.Client.5.6.4\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=6.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\WindowsAzure.Storage.6.2.0\\lib\\net40\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.ComponentModel.Composition\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Rx-Core.2.2.5\\lib\\net45\\System.Reactive.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Rx-Interfaces.2.2.5\\lib\\net45\\System.Reactive.Interfaces.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Rx-Linq.2.2.5\\lib\\net45\\System.Reactive.Linq.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Rx-PlatformServices.2.2.5\\lib\\net45\\System.Reactive.PlatformServices.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.6.4\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Windows.Forms\" />\n    <Reference Include=\"System.Xml\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xaml\">\n      <RequiredTargetFramework>4.0</RequiredTargetFramework>\n    </Reference>\n    <Reference Include=\"WindowsBase\" />\n    <Reference Include=\"PresentationCore\" />\n    <Reference Include=\"PresentationFramework\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ApplicationDefinition Include=\"App.xaml\">\n      <Generator>MSBuild:Compile</Generator>\n      <SubType>Designer</SubType>\n    </ApplicationDefinition>\n    <Compile Include=\"AddNewDeploymentDialog.xaml.cs\">\n      <DependentUpon>AddNewDeploymentDialog.xaml</DependentUpon>\n    </Compile>\n    <Compile Include=\"DeploymentInfo.cs\" />\n    <Compile Include=\"DeploymentRepositoryFactory.cs\" />\n    <Compile Include=\"IDeploymentRepositoryFactory.cs\" />\n    <Compile Include=\"SelectDirectoryControl.xaml.cs\">\n      <DependentUpon>SelectDirectoryControl.xaml</DependentUpon>\n    </Compile>\n    <Compile Include=\"StorageAccountConnectionInfo.cs\" />\n    <Compile Include=\"UpdateVersionDialog.xaml.cs\">\n      <DependentUpon>UpdateVersionDialog.xaml</DependentUpon>\n    </Compile>\n    <Compile Include=\"DeploymentRepositoryManager.cs\" />\n    <Page Include=\"AddNewApplicationDialog.xaml\">\n      <SubType>Designer</SubType>\n      <Generator>MSBuild:Compile</Generator>\n    </Page>\n    <Page Include=\"AddNewDeploymentDialog.xaml\">\n      <SubType>Designer</SubType>\n      <Generator>MSBuild:Compile</Generator>\n    </Page>\n    <Page Include=\"BusyWindow.xaml\">\n      <SubType>Designer</SubType>\n      <Generator>MSBuild:Compile</Generator>\n    </Page>\n    <Page Include=\"ConnectToStorageAccountDialog.xaml\">\n      <SubType>Designer</SubType>\n      <Generator>MSBuild:Compile</Generator>\n    </Page>\n    <Page Include=\"MainWindow.xaml\">\n      <Generator>MSBuild:Compile</Generator>\n      <SubType>Designer</SubType>\n    </Page>\n    <Compile Include=\"AddNewApplicationDialog.xaml.cs\">\n      <DependentUpon>AddNewApplicationDialog.xaml</DependentUpon>\n    </Compile>\n    <Compile Include=\"App.xaml.cs\">\n      <DependentUpon>App.xaml</DependentUpon>\n      <SubType>Code</SubType>\n    </Compile>\n    <Compile Include=\"BusyWindow.xaml.cs\">\n      <DependentUpon>BusyWindow.xaml</DependentUpon>\n    </Compile>\n    <Compile Include=\"ConnectToStorageAccountDialog.xaml.cs\">\n      <DependentUpon>ConnectToStorageAccountDialog.xaml</DependentUpon>\n    </Compile>\n    <Compile Include=\"MainWindow.xaml.cs\">\n      <DependentUpon>MainWindow.xaml</DependentUpon>\n      <SubType>Code</SubType>\n    </Compile>\n    <Page Include=\"SelectDirectoryControl.xaml\">\n      <SubType>Designer</SubType>\n      <Generator>MSBuild:Compile</Generator>\n    </Page>\n    <Page Include=\"UpdateVersionDialog.xaml\">\n      <SubType>Designer</SubType>\n      <Generator>MSBuild:Compile</Generator>\n    </Page>\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\">\n      <SubType>Code</SubType>\n    </Compile>\n    <Compile Include=\"Properties\\Resources.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DesignTime>True</DesignTime>\n      <DependentUpon>Resources.resx</DependentUpon>\n    </Compile>\n    <Compile Include=\"Properties\\Settings.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Settings.settings</DependentUpon>\n      <DesignTimeSharedInput>True</DesignTimeSharedInput>\n    </Compile>\n    <EmbeddedResource Include=\"Properties\\Resources.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n    </EmbeddedResource>\n    <None Include=\"packages.config\">\n      <SubType>Designer</SubType>\n    </None>\n    <None Include=\"Properties\\Settings.settings\">\n      <Generator>SettingsSingleFileGenerator</Generator>\n      <LastGenOutput>Settings.Designer.cs</LastGenOutput>\n    </None>\n    <AppDesigner Include=\"Properties\\\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "Samples/YamsStudio/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net461\" />\n  <package id=\"EnterpriseLibrary.TransientFaultHandling\" version=\"6.0.1304.0\" targetFramework=\"net461\" />\n  <package id=\"Etg.Yams\" version=\"1.1.0-rc\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.6.4\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.6.4\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.6.4\" targetFramework=\"net461\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net461\" />\n  <package id=\"Rx-Core\" version=\"2.2.5\" targetFramework=\"net461\" />\n  <package id=\"Rx-Interfaces\" version=\"2.2.5\" targetFramework=\"net461\" />\n  <package id=\"Rx-Linq\" version=\"2.2.5\" targetFramework=\"net461\" />\n  <package id=\"Rx-Main\" version=\"2.2.5\" targetFramework=\"net461\" />\n  <package id=\"Rx-PlatformServices\" version=\"2.2.5\" targetFramework=\"net461\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net461\" />\n  <package id=\"System.Runtime\" version=\"4.1.0\" targetFramework=\"net461\" />\n  <package id=\"System.Runtime.Extensions\" version=\"4.1.0\" targetFramework=\"net461\" />\n  <package id=\"System.Runtime.InteropServices\" version=\"4.1.0\" targetFramework=\"net461\" />\n  <package id=\"System.Spatial\" version=\"5.6.4\" targetFramework=\"net461\" />\n  <package id=\"System.Text.RegularExpressions\" version=\"4.1.0\" targetFramework=\"net461\" />\n  <package id=\"WindowsAzure.Storage\" version=\"6.2.0\" targetFramework=\"net461\" />\n</packages>"
  },
  {
    "path": "src/AzureBlobStorageDeploymentRepository/AzureBlobStorageDeploymentRepository.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{DF95A9DC-F6BE-4C71-B444-4092B43EB602}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Azure.Storage</RootNamespace>\n    <AssemblyName>Etg.Yams.AzureBlobStorageDeploymentRepository</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\netstandard1.1\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.ComponentModel.Composition\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"BlobStorageDeploymentRepository.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\AzureUtils\\AzureUtils.csproj\">\n      <Project>{1c890e49-5a9b-4eab-9f69-6a6e78d82610}</Project>\n      <Name>AzureUtils</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Common\\Common.csproj\">\n      <Project>{3e982150-5b43-44da-8d96-66cf07a9a14c}</Project>\n      <Name>Common</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Etg.Yams.Core\\Etg.Yams.Core.csproj\">\n      <Project>{7145e485-34fa-4632-89b0-bd27c96af69c}</Project>\n      <Name>Etg.Yams.Core</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "src/AzureBlobStorageDeploymentRepository/BlobStorageDeploymentRepository.cs",
    "content": "﻿using System.Diagnostics;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Azure.Utils;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Utils;\nusing Microsoft.WindowsAzure.Storage.Blob;\nusing Etg.Yams.Json;\nusing Newtonsoft.Json.Serialization;\nusing Etg.Yams.Storage.Status;\nusing System;\nusing System.Collections.Generic;\nusing Etg.Yams.Azure.Lease;\n\nnamespace Etg.Yams.Azure.Storage\n{\n    public class BlobStorageDeploymentRepository : IDeploymentRepository, IDeploymentStatusReader, IDeploymentStatusWriter\n    {\n        public const string ApplicationsRootFolderName = \"applications\";\n        private readonly CloudBlobContainer _blobContainer;\n        private readonly IDeploymentConfigSerializer _deploymentConfigSerializer;\n        private readonly IDeploymentStatusSerializer _deploymentStatusSerializer;\n\n        public BlobStorageDeploymentRepository(CloudBlobContainer blobContainer, IDeploymentConfigSerializer serializer,\n            IDeploymentStatusSerializer deploymentStatusSerializer)\n        {\n            _blobContainer = blobContainer;\n            _deploymentConfigSerializer = serializer;\n            _deploymentStatusSerializer = deploymentStatusSerializer;\n        }\n\n        public BlobStorageDeploymentRepository(string connectionString, IDeploymentConfigSerializer deploymentConfigSerializer,\n            IDeploymentStatusSerializer deploymentStatusSerializer) \n            : this(GetApplicationsContainerReference(connectionString), deploymentConfigSerializer, deploymentStatusSerializer)\n        {\n        }\n\n        public static BlobStorageDeploymentRepository Create(string connectionString)\n        {\n            var jsonSerializer = new JsonSerializer(new DiagnosticsTraceWriter());\n            IDeploymentConfigSerializer deploymentConfigSerializer = new JsonDeploymentConfigSerializer(jsonSerializer);\n            IDeploymentStatusSerializer deploymentStatusSerializer = new JsonDeploymentStatusSerializer(jsonSerializer);\n            return new BlobStorageDeploymentRepository(connectionString, deploymentConfigSerializer, deploymentStatusSerializer);\n        }\n\n        private static CloudBlobContainer GetApplicationsContainerReference(string connectionString)\n        {\n            CloudBlobContainer blobContainer = BlobUtils.GetBlobContainer(connectionString,\n                ApplicationsRootFolderName);\n            return blobContainer;\n        }\n\n        public async Task DeleteApplicationBinaries(AppIdentity appIdentity)\n        {\n            CloudBlobDirectory blobDirectory = GetBlobDirectory(appIdentity);\n            if (!await blobDirectory.ExistsAsync())\n            {\n                throw new BinariesNotFoundException(\n                    $\"Cannot delete binaries for application {appIdentity} because they were not found\");\n            }\n            await blobDirectory.DeleteAsync();\n        }\n\n        public async Task<DeploymentConfig> FetchDeploymentConfig()\n        {\n            var blob = _blobContainer.GetBlockBlobReference(Constants.DeploymentConfigFileName);\n            if (!await blob.ExistsAsync())\n            {\n                Trace.TraceInformation(\"The DeploymentConfig.json file was not found in the Yams repository\");\n                return new DeploymentConfig();\n            }\n\n            string data = await blob.DownloadTextAsync();\n            return _deploymentConfigSerializer.Deserialize(data);\n        }\n\n        public Task<bool> HasApplicationBinaries(AppIdentity appIdentity)\n        {\n            return GetBlobDirectory(appIdentity).ExistsAsync();\n        }\n\n        public async Task DownloadApplicationBinaries(AppIdentity appIdentity, string localPath,\n            ConflictResolutionMode conflictResolutionMode)\n        {\n            bool exists = !FileUtils.DirectoryDoesntExistOrEmpty(localPath);\n            if (exists)\n            {\n                if (conflictResolutionMode == ConflictResolutionMode.DoNothingIfBinariesExist)\n                {\n                    return;\n                }\n                if (conflictResolutionMode == ConflictResolutionMode.FailIfBinariesExist)\n                {\n                    throw new DuplicateBinariesException(\n                        $\"Cannot download the binaries because the destination directory {localPath} contains files\");\n                }\n            }\n            CloudBlobDirectory blobDirectory = GetBlobDirectory(appIdentity);\n            if (!await blobDirectory.ExistsAsync())\n            {\n                throw new BinariesNotFoundException(\"The binaries were not found in the Yams repository\");\n            }\n            await BlobUtils.DownloadBlobDirectory(blobDirectory, localPath);\n        }\n\n        public Task PublishDeploymentConfig(DeploymentConfig deploymentConfig)\n        {\n            CloudBlockBlob blob = _blobContainer.GetBlockBlobReference(Constants.DeploymentConfigFileName);\n            return blob.UploadTextAsync(_deploymentConfigSerializer.Serialize(deploymentConfig));\n        }\n\n        public async Task UploadApplicationBinaries(AppIdentity appIdentity, string localPath,\n            ConflictResolutionMode conflictResolutionMode)\n        {\n            if (FileUtils.DirectoryDoesntExistOrEmpty(localPath))\n            {\n                throw new BinariesNotFoundException(\n                    $\"Binaries were not be uploaded because they were not found at the given path {localPath}\");\n            }\n\n            if (conflictResolutionMode == ConflictResolutionMode.OverwriteExistingBinaries)\n            {\n                await DeleteApplicationBinaries(appIdentity);\n            }\n            else\n            {\n                bool exists = await HasApplicationBinaries(appIdentity);\n\n                if (exists)\n                {\n                    if (conflictResolutionMode == ConflictResolutionMode.DoNothingIfBinariesExist)\n                    {\n                        return;\n                    }\n\n                    if (conflictResolutionMode == ConflictResolutionMode.FailIfBinariesExist)\n                    {\n                        throw new DuplicateBinariesException(\n                            $\"Cannot override binaries when flag {ConflictResolutionMode.FailIfBinariesExist} is used\");\n                    }\n                }\n            }\n\n            // at this point we know that it is either OverwriteExistingBinaries mode or the binaries don't exist\n            await BlobUtils.UploadDirectory(localPath, _blobContainer, GetBlobDirectoryRelPath(appIdentity));\n        }\n\n        private CloudBlobDirectory GetBlobDirectory(AppIdentity appIdentity)\n        {\n            string relPath = GetBlobDirectoryRelPath(appIdentity);\n            return _blobContainer.GetDirectoryReference(relPath);\n        }\n\n        private string GetBlobDirectoryRelPath(AppIdentity appIdentity)\n        {\n            return appIdentity.Id + \"/\" + appIdentity.Version;\n        }\n\n        public async Task<ClusterDeploymentStatus> FetchClusterDeploymentStatus(string clusterId, int ttlSeconds)\n        {\n            ClusterDeploymentStatus clusterDeploymentStatus = new ClusterDeploymentStatus();;\n            CloudBlobDirectory instancesBlobDir = _blobContainer.GetDirectoryReference(GetClusterStatusRelativePath(clusterId));\n            if (!await instancesBlobDir.ExistsAsync())\n            {\n                return clusterDeploymentStatus;\n            }\n            IEnumerable<IListBlobItem> instancesBlobList = await instancesBlobDir.ListBlobsAsync();\n            foreach (var blob in instancesBlobList)\n            {\n                CloudBlockBlob instanceBlob = blob as CloudBlockBlob;\n                if (instanceBlob == null)\n                {\n                    Trace.TraceWarning($\"Unexpected blob {blob.Uri} in cluster status directory\");\n                    continue;\n                }\n                double secondsSinceModified = DateTimeOffset.UtcNow.Subtract(instanceBlob.Properties.LastModified.Value).TotalSeconds;\n                if (secondsSinceModified > ttlSeconds)\n                {\n                    continue;\n                }\n\n                try\n                {\n                    InstanceDeploymentStatus instanceDeploymentStatus =\n                        await FetchInstanceDeploymentStatus(instanceBlob);\n                    string instanceId = instanceBlob.Name;\n                    clusterDeploymentStatus.SetInstanceDeploymentStatus(instanceId, instanceDeploymentStatus);\n                }\n                catch (Exception e)\n                {\n                    Trace.TraceError($\"Could not read instance deployment status {instanceBlob.Uri}, Exception: {e}\");\n                }\n            }\n            return clusterDeploymentStatus;\n        }\n\n        public async Task<InstanceDeploymentStatus> FetchInstanceDeploymentStatus(string clusterId, string instanceId)\n        {\n            CloudBlockBlob instanceBlob =\n                _blobContainer.GetBlockBlobReference(GetInstanceStatusRelativePath(clusterId, instanceId));\n            if (!await instanceBlob.ExistsAsync())\n            {\n                return new InstanceDeploymentStatus();\n            }\n            return await FetchInstanceDeploymentStatus(instanceBlob);\n        }\n\n        private static string GetClusterStatusRelativePath(string clusterId)\n        {\n            return $\"status/clusters/{clusterId}/instances\";\n        }\n\n        private static string GetInstanceStatusRelativePath(string clusterId, string instanceId)\n        {\n            return $\"{GetClusterStatusRelativePath(clusterId)}/{instanceId}\";\n        }\n\n        private async Task<InstanceDeploymentStatus> FetchInstanceDeploymentStatus(CloudBlockBlob instanceBlob)\n        {\n            string data = await instanceBlob.DownloadTextAsync();\n            return _deploymentStatusSerializer.Deserialize(data);\n        }\n\n        public Task PublishInstanceDeploymentStatus(string clusterId, string instanceId, \n            InstanceDeploymentStatus instanceDeploymentStatus)\n        {\n            CloudBlockBlob blob = _blobContainer.GetBlockBlobReference(GetInstanceStatusRelativePath(clusterId, instanceId));\n            string data = _deploymentStatusSerializer.Serialize(instanceDeploymentStatus);\n            return blob.UploadTextAsync(data);\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageDeploymentRepository/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"AzureBlobStorageDeploymentRepository\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"AzureBlobStorageDeploymentRepository\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"df95a9dc-f6be-4c71-b444-4092b43eb602\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/AzureBlobStorageDeploymentRepository/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n    </assemblyBinding>\n  </runtime>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" /></startup></configuration>\n"
  },
  {
    "path": "src/AzureBlobStorageDeploymentRepository/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net451\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Runtime\" version=\"4.1.0\" targetFramework=\"net451\" />\n  <package id=\"System.Runtime.Extensions\" version=\"4.1.0\" targetFramework=\"net451\" />\n  <package id=\"System.Runtime.InteropServices\" version=\"4.1.0\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"System.Text.RegularExpressions\" version=\"4.1.0\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/AzureBlobStorageUpdateSession.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{894B7986-5AA4-42A7-8EB0-6DFD1F604505}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Azure</RootNamespace>\n    <AssemblyName>Etg.Yams.AzureBlobStorageUpdateSession</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"UpdateSession\\AzureTableUpdateSessionManager.cs\" />\n    <Compile Include=\"UpdateSession\\AzureStorageUpdateSessionDiModule.cs\" />\n    <Compile Include=\"UpdateSession\\IUpdateBlob.cs\" />\n    <Compile Include=\"UpdateSession\\IUpdateBlobFactory.cs\" />\n    <Compile Include=\"UpdateSession\\IUpdateSessionTable.cs\" />\n    <Compile Include=\"UpdateSession\\Retry\\LockUpdateBlobErrorDetectionStrategy.cs\" />\n    <Compile Include=\"UpdateSession\\Retry\\StartUpdateSessionRetryDecorator.cs\" />\n    <Compile Include=\"UpdateSession\\Retry\\StorageExceptionErrorDetectionStrategy.cs\" />\n    <Compile Include=\"UpdateSession\\UpdateBlob.cs\" />\n    <Compile Include=\"UpdateSession\\UpdateBlobFactory.cs\" />\n    <Compile Include=\"UpdateSession\\Retry\\UpdateBlobFactoryRetryLockDecorator.cs\" />\n    <Compile Include=\"UpdateSession\\UpdateBlobUnavailableException.cs\" />\n    <Compile Include=\"UpdateSession\\Retry\\StorageExceptionUpdateSessionRetryDecorator.cs\" />\n    <Compile Include=\"UpdateSession\\UpdateDomainEntity.cs\" />\n    <Compile Include=\"UpdateSession\\UpdateSessionStatus.cs\" />\n    <Compile Include=\"UpdateSession\\UpdateSessionTable.cs\" />\n    <Compile Include=\"UpdateSession\\UpdateSessionTransaction.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\AzureUtils\\AzureUtils.csproj\">\n      <Project>{1c890e49-5a9b-4eab-9f69-6a6e78d82610}</Project>\n      <Name>AzureUtils</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Etg.Yams.Core\\Etg.Yams.Core.csproj\">\n      <Project>{7145e485-34fa-4632-89b0-bd27c96af69c}</Project>\n      <Name>Etg.Yams.Core</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"AzureBlobStorageUpdateSession\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"AzureBlobStorageUpdateSession\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"894b7986-5aa4-42a7-8eb0-6dfd1f604505\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/AzureStorageUpdateSessionDiModule.cs",
    "content": "﻿using System;\nusing Autofac;\nusing Etg.Yams.Azure.UpdateSession.Retry;\nusing Etg.Yams.Update;\nusing Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public class AzureStorageUpdateSessionDiModule\n    {\n        private readonly IContainer _container;\n        private const string UpdateSessionRetryStrategyModuleName = \"updateSessionRetryStrategy\";\n\n        public AzureStorageUpdateSessionDiModule(\n            string superClusterId,\n            string clusterId,\n            string instanceId,\n            string updateDomain,\n            string connectionString,\n            TimeSpan updateSessionTtl,\n            int storageExceptionRetryCount = 20,\n            int storageExceptionRetryIntervalInSeconds = 1,\n            int startUpdateSessionRetryCount = 20,\n            int startUpdateSessionRetryIntervalInSeconds = 5) : this(RegisterTypes(\n                superClusterId, clusterId, instanceId, updateDomain, connectionString, updateSessionTtl,\n                storageExceptionRetryCount, storageExceptionRetryIntervalInSeconds,\n                startUpdateSessionRetryCount, startUpdateSessionRetryIntervalInSeconds).Build())\n        {\n        }\n\n        public AzureStorageUpdateSessionDiModule(IContainer container)\n        {\n            _container = container;\n        }\n\n        public static ContainerBuilder RegisterTypes(\n            string superClusterId,\n            string clusterId,\n            string instanceId,\n            string updateDomain,\n            string connectionString,\n            TimeSpan updateSessionTtl,\n            int storageExceptionRetryCount = 20,\n            int storageExceptionRetryIntervalInSeconds = 1,\n            int startUpdateSessionRetryCount = 5,\n            int startUpdateSessionRetryIntervalInSeconds = 1)\n        {\n            var containerBuilder = new ContainerBuilder();\n\n            containerBuilder.Register<RetryStrategy>(\n                c => new FixedInterval(storageExceptionRetryCount, TimeSpan.FromSeconds(storageExceptionRetryIntervalInSeconds)))\n                .Named<RetryStrategy>(UpdateSessionRetryStrategyModuleName).SingleInstance();\n\n            containerBuilder.Register(\n                c => new AzureTableUpdateSessionManager(c.Resolve<IUpdateSessionTable>(), clusterId, instanceId,\n                    updateDomain));\n\n            containerBuilder.RegisterInstance(new UpdateSessionTable(connectionString, updateSessionTtl))\n                .As<IUpdateSessionTable>();\n            containerBuilder.Register<IUpdateSessionManager>(\n                c => \n                new StartUpdateSessionRetryDecorator(\n                new StorageExceptionUpdateSessionRetryDecorator(\n                    c.Resolve<AzureTableUpdateSessionManager>(),\n                    c.ResolveNamed<RetryStrategy>(UpdateSessionRetryStrategyModuleName),\n                    new StorageExceptionErrorDetectionStrategy()), startUpdateSessionRetryCount, \n                TimeSpan.FromSeconds(startUpdateSessionRetryIntervalInSeconds)));\n            return containerBuilder;\n        }\n\n        public IContainer Container => _container;\n\n        public IUpdateSessionManager UpdateSessionManager => _container.Resolve<IUpdateSessionManager>();\n    }\n}\n"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/AzureTableUpdateSessionManager.cs",
    "content": "using System.Diagnostics;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Etg.Yams.Update;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public class AzureTableUpdateSessionManager : IUpdateSessionManager\n    {\n        public const string UpdateSessionTableName = \"YamsUpdateSession\";\n        private readonly IUpdateSessionTable _updateSessionTable;\n        private readonly string _superClusterId;\n        private readonly string _instanceId;\n        private readonly string _instanceUpdateDomain;\n\n        public AzureTableUpdateSessionManager(IUpdateSessionTable updateSessionTable, string superClusterId, \n            string instanceId, string instanceUpdateDomain)\n        {\n            _updateSessionTable = updateSessionTable;\n            _superClusterId = superClusterId;\n            _instanceId = instanceId;\n            _instanceUpdateDomain = instanceUpdateDomain;\n        }\n\n        public async Task<bool> TryStartUpdateSession()\n        {\n            Trace.TraceInformation(\n                $\"Instance {_instanceId} will attempt to start update session\" +\n                $\", UpdateDomain = {_instanceUpdateDomain}\");\n\n            UpdateSessionTransaction transaction = new UpdateSessionTransaction(_superClusterId, _instanceId, _instanceUpdateDomain);\n            UpdateSessionStatus updateSessionStatus = await _updateSessionTable.FetchUpdateSessionStatus(_superClusterId);\n\n            if (updateSessionStatus.UpdateDomainEntity == null ||\n                updateSessionStatus.UpdateDomainEntity.UpdateDomain == _instanceUpdateDomain)\n            {\n                if (updateSessionStatus.UpdateDomainEntity == null)\n                {\n                    transaction.InsertUpdateDomain();\n                }\n                \n                transaction.MarkInstanceListAsModified();\n            }\n            else if (!updateSessionStatus.InstancesEntities.Any()) // no instance in the current update domain is updating\n            {\n                // set a new update domain (if no other instance beats us to it)\n                transaction.ReplaceUpdateDomain(updateSessionStatus); // will fail if current update domain changes\n                transaction.FailIfInstanceListModified(updateSessionStatus); // will fail if instance list changes\n            }\n            else\n            {\n                return false;\n            }\n\n            // enlist the current instance (this will succeed even if the active update domain is different but we \n            // won't start the update session, see below)\n            transaction.InsertOrReplaceInstance();\n\n            if (await _updateSessionTable.TryExecuteTransaction(transaction))\n            {\n                // handle the case where an instance enlisted itself after the update domain has changed,\n                string updateDomain = await _updateSessionTable.GetActiveUpdateDomain(_superClusterId);\n                if (updateDomain != _instanceUpdateDomain)\n                {\n                    // Note that deleting this row is optional because it will filtered out anyway when list of instances\n                    // of the active update domain is loaded (as a result, it's not an issue if this fails).\n                    // We delete it anyway to keep the table clean.\n                    await _updateSessionTable.DeleteInstanceEntity(_superClusterId, _instanceId);\n                    return false;\n                }\n                Trace.TraceInformation(\n                    $\"Instance {_instanceId} successfully started the update session\" +\n                    $\", UpdateDomain = {_instanceUpdateDomain}\");\n                return true;\n            }\n\n            return false;\n        }\n\n        public async Task EndUpdateSession()\n        {\n            Trace.TraceInformation(\n                $\"Instance {_instanceId} Will attempt to end the update session\" +\n                $\", UpdateDomain = {_instanceUpdateDomain}\");\n\n            await _updateSessionTable.DeleteInstanceEntity(_superClusterId, _instanceId);\n\n            Trace.TraceInformation(\n                $\"Instance {_instanceId} successfully ended the update session\" +\n                $\", UpdateDomain = {_instanceUpdateDomain}\");\n\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/IUpdateBlob.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public interface IUpdateBlob : IDisposable\n    {\n        void AddInstance(string instanceId);\n        void RemoveInstance(string instanceId);\n        string GetUpdateDomain();\n        ISet<string> GetInstanceIds();\n        Task<bool> TryLock();\n        Task FlushAndRelease();\n        void SetUpdateDomain(string updateDomain);\n        Task Release();\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/IUpdateBlobFactory.cs",
    "content": "﻿using System.Threading.Tasks;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public interface IUpdateBlobFactory\n    {\n        Task<IUpdateBlob> TryLockUpdateBlob(string appId);\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/IUpdateSessionTable.cs",
    "content": "using System.Threading.Tasks;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public interface IUpdateSessionTable\n    {\n        Task<UpdateSessionStatus> FetchUpdateSessionStatus(string clusterId);\n        Task<bool> TryExecuteTransaction(UpdateSessionTransaction transaction);\n        Task DeleteInstanceEntity(string clusterId, string instanceId);\n        Task<string> GetActiveUpdateDomain(string clusterId);\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/Retry/LockUpdateBlobErrorDetectionStrategy.cs",
    "content": "using System;\nusing Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;\n\nnamespace Etg.Yams.Azure.UpdateSession.Retry\n{\n    public class LockUpdateBlobErrorDetectionStrategy : ITransientErrorDetectionStrategy\n    {\n        public bool IsTransient(Exception ex)\n        {\n            return ex is UpdateBlobUnavailableException;\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/Retry/StartUpdateSessionRetryDecorator.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing Etg.Yams.Update;\n\nnamespace Etg.Yams.Azure.UpdateSession.Retry\n{\n    public class StartUpdateSessionRetryDecorator : IUpdateSessionManager\n    {\n        private readonly IUpdateSessionManager _updateSessionManager;\n        private readonly int _retryCount;\n        private readonly TimeSpan _retryInterval;\n\n        public StartUpdateSessionRetryDecorator(IUpdateSessionManager updateSessionManager, int retryCount,\n            TimeSpan retryInterval)\n        {\n            _updateSessionManager = updateSessionManager;\n            _retryCount = retryCount;\n            _retryInterval = retryInterval;\n        }\n\n        public async Task<bool> TryStartUpdateSession()\n        {\n            int count = 0;\n            while (count <= _retryCount)\n            {\n                if (await _updateSessionManager.TryStartUpdateSession())\n                {\n                    return true;\n                }\n\n                ++count;\n                if (count <= _retryCount)\n                {\n                    await Task.Delay(_retryInterval);\n                }\n            }\n            return false;\n        }\n\n        public Task EndUpdateSession()\n        {\n            return _updateSessionManager.EndUpdateSession();\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/Retry/StorageExceptionErrorDetectionStrategy.cs",
    "content": "﻿using System;\nusing System.Net;\nusing Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;\nusing Microsoft.WindowsAzure.Storage;\n\nnamespace Etg.Yams.Azure.UpdateSession.Retry\n{\n    public class StorageExceptionErrorDetectionStrategy : ITransientErrorDetectionStrategy\n    {\n        public bool IsTransient(Exception ex)\n        {\n            return ex is StorageException || ex is WebException;\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/Retry/StorageExceptionUpdateSessionRetryDecorator.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Update;\nusing Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;\n\nnamespace Etg.Yams.Azure.UpdateSession.Retry\n{\n    public class StorageExceptionUpdateSessionRetryDecorator : IUpdateSessionManager\n    {\n        private readonly IUpdateSessionManager _updateSessionManager;\n        private readonly RetryPolicy _retryPolicy;\n\n        public StorageExceptionUpdateSessionRetryDecorator(IUpdateSessionManager updateSessionManager,\n            RetryStrategy retryStrategy,\n            ITransientErrorDetectionStrategy errorDetectionStrategy)\n        {\n            _updateSessionManager = updateSessionManager;\n            _retryPolicy = new RetryPolicy(errorDetectionStrategy, retryStrategy);\n        }\n\n        public Task<bool> TryStartUpdateSession()\n        {\n            return _retryPolicy.ExecuteAsync(async () => await _updateSessionManager.TryStartUpdateSession());\n        }\n\n        public Task EndUpdateSession()\n        {\n            return _retryPolicy.ExecuteAsync(async () => await _updateSessionManager.EndUpdateSession());\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/Retry/UpdateBlobFactoryRetryLockDecorator.cs",
    "content": "using System.Threading.Tasks;\nusing Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;\n\nnamespace Etg.Yams.Azure.UpdateSession.Retry\n{\n    public class UpdateBlobFactoryRetryLockDecorator : IUpdateBlobFactory\n    {\n        private readonly IUpdateBlobFactory _updateBlobFactory;\n        private readonly RetryPolicy _retryPolicy;\n\n        public UpdateBlobFactoryRetryLockDecorator(IUpdateBlobFactory updateBlobFactory, RetryStrategy retryStrategy)\n        {\n            _updateBlobFactory = updateBlobFactory;\n            _retryPolicy = new RetryPolicy(new LockUpdateBlobErrorDetectionStrategy(), retryStrategy);\n        }\n\n        public Task<IUpdateBlob> TryLockUpdateBlob(string appId)\n        {\n            return _retryPolicy.ExecuteAsync(() => _updateBlobFactory.TryLockUpdateBlob(appId));\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/UpdateBlob.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Net;\nusing System.Threading.Tasks;\nusing Etg.Yams.Azure.Lease;\nusing Microsoft.WindowsAzure.Storage;\nusing Microsoft.WindowsAzure.Storage.Blob;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public class UpdateBlob : IUpdateBlob\n    {\n        private const string UpdateDomainKey = \"UpdateDomain\";\n        private const string UpdateDomainInstancesKey = \"UpdateDomainInstances\";\n\n        private readonly ICloudBlob _blob;\n        private readonly IBlobLeaseFactory _blobLeaseFactory;\n        private string _updateDomain;\n        private HashSet<string> _instanceIds;\n        private string _leaseId;\n        private IBlobLease _lease;\n\n        public UpdateBlob(ICloudBlob blob, IBlobLeaseFactory blobLeaseFactory)\n        {\n            _blob = blob;\n            _blobLeaseFactory = blobLeaseFactory;\n            _updateDomain = string.Empty;\n            _instanceIds = new HashSet<string>();\n        }\n\n        public void SetUpdateDomain(string updateDomain)\n        {\n            EnsureThatBlobIsLocked();\n            _updateDomain = updateDomain;\n        }\n\n        private void EnsureThatBlobIsLocked()\n        {\n            if (_lease == null)\n            {\n                throw new InvalidOperationException(\"The updated blob must be locked before being accessed\");\n            }\n        }\n\n        public void AddInstance(string instanceId)\n        {\n            EnsureThatBlobIsLocked();\n            _instanceIds.Add(instanceId);\n        }\n\n        public void RemoveInstance(string instanceId)\n        {\n            EnsureThatBlobIsLocked();\n            _instanceIds.Remove(instanceId);\n        }\n\n        public string GetUpdateDomain()\n        {\n            EnsureThatBlobIsLocked();\n            return _updateDomain;\n        }\n\n        public ISet<string> GetInstanceIds()\n        {\n            EnsureThatBlobIsLocked();\n            return _instanceIds;\n        }\n\n        public async Task<bool> TryLock()\n        {\n            try\n            {\n                _lease = _blobLeaseFactory.CreateLease(_blob);\n                _leaseId = await _lease.TryAcquireLease();\n                if (_leaseId == null)\n                {\n                    DisposeLease();\n                    return false;\n                }\n                await _blob.FetchAttributesAsync();\n\n                if (_blob.Metadata.ContainsKey(UpdateDomainInstancesKey))\n                {\n                    string[] instanceIds = _blob.Metadata[UpdateDomainInstancesKey].Split(',');\n                    _instanceIds = new HashSet<string>(instanceIds);\n                }\n                _updateDomain = _blob.Metadata.ContainsKey(UpdateDomainKey) ? _blob.Metadata[UpdateDomainKey] : string.Empty;\n\n                return true;\n            }\n            catch (Exception e)\n            {\n                if (e is StorageException || e is WebException)\n                {\n                    DisposeLease();\n                    Trace.TraceInformation($\"Failed to acquire the lease on blob {_blob.Name}\", e);\n                    return false;\n                }\n                throw;\n            }\n        }\n\n        private void DisposeLease()\n        {\n            _leaseId = null;\n            _lease.Dispose();\n            _lease = null;\n        }\n\n        private Task FlushBlobMetadata()\n        {\n            if (_instanceIds.Any())\n            {\n                if (string.IsNullOrEmpty(_updateDomain))\n                {\n                    throw new InvalidOperationException(\"Update domain should be set before setting instance ids\");\n                }\n                _blob.Metadata[UpdateDomainInstancesKey] = string.Join(\",\", _instanceIds);\n                _blob.Metadata[UpdateDomainKey] = _updateDomain;\n            }\n            else\n            {\n                _blob.Metadata.Remove(UpdateDomainKey);\n                _blob.Metadata.Remove(UpdateDomainInstancesKey);\n            }\n            return _blob.SetMetadataAsync(\n                new AccessCondition\n                {\n                    LeaseId = _leaseId\n                }, new BlobRequestOptions(), new OperationContext());\n        }\n\n        public async Task FlushAndRelease()\n        {\n            EnsureThatBlobIsLocked();\n            await FlushBlobMetadata();\n            await Release();\n        }\n\n        public async Task Release()\n        {\n            await _lease.ReleaseLease();\n            DisposeLease();\n        }\n\n        public void Dispose()\n        {\n            if (_lease != null)\n            {\n                Release().Wait();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/UpdateBlobFactory.cs",
    "content": "using System.Threading.Tasks;\nusing Etg.Yams.Azure.Lease;\nusing Etg.Yams.Azure.Utils;\nusing Microsoft.WindowsAzure.Storage.Blob;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public class UpdateBlobFactory : IUpdateBlobFactory\n    {\n        private readonly string _clusterId;\n        private readonly CloudBlobContainer _blobContainer;\n        private readonly IBlobLeaseFactory _blobLeaseFactory;\n\n        public UpdateBlobFactory(string clusterId, CloudBlobContainer blobContainer, IBlobLeaseFactory blobLeaseFactory)\n        {\n            _clusterId = clusterId;\n            _blobContainer = blobContainer;\n            _blobLeaseFactory = blobLeaseFactory;\n        }\n\n        public async Task<IUpdateBlob> TryLockUpdateBlob(string appId)\n        {\n            string updateBlobName = GetUpdateBlobName(appId);\n            ICloudBlob blob = GetBlob(updateBlobName);\n            await BlobUtils.CreateBlobIfNotExists(blob);\n\n            UpdateBlob updateBlob = new UpdateBlob(blob, _blobLeaseFactory);\n            bool locked = await updateBlob.TryLock();\n            if (locked == false)\n            {\n                throw new UpdateBlobUnavailableException();\n            }\n            return updateBlob;\n        }\n\n        private string GetUpdateBlobName(string applicationId)\n        {\n            return _clusterId + \"_\" + applicationId + \"_update_blob\";\n        }\n\n        private CloudBlockBlob GetBlob(string updateBlobName)\n        {\n            return _blobContainer.GetBlockBlobReference(updateBlobName);\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/UpdateBlobUnavailableException.cs",
    "content": "using System;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public class UpdateBlobUnavailableException : Exception\n    {\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/UpdateDomainEntity.cs",
    "content": "using Microsoft.WindowsAzure.Storage.Table;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public class UpdateDomainEntity : TableEntity\n    {\n        public UpdateDomainEntity()\n        {\n        }\n\n        public UpdateDomainEntity(string partitionKey, string rowKey, string updateDomain)\n            : base(partitionKey, rowKey)\n        {\n            UpdateDomain = updateDomain;\n        }\n\n        public string UpdateDomain\n        {\n            get; set;\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/UpdateSessionStatus.cs",
    "content": "using System.Collections.Generic;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public class UpdateSessionStatus\n    {\n        public IEnumerable<UpdateDomainEntity> InstancesEntities { get; }\n        public UpdateDomainEntity ModifiedEntity { get; }\n        public UpdateDomainEntity UpdateDomainEntity { get; }\n\n        public UpdateSessionStatus(IEnumerable<UpdateDomainEntity> instancesEntities, UpdateDomainEntity modifiedEntity,\n            UpdateDomainEntity updateDomainEntity)\n        {\n            InstancesEntities = instancesEntities;\n            ModifiedEntity = modifiedEntity;\n            UpdateDomainEntity = updateDomainEntity;\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/UpdateSessionTable.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Microsoft.WindowsAzure.Storage;\nusing Microsoft.WindowsAzure.Storage.Table;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public class UpdateSessionTable : IUpdateSessionTable\n    {\n        private readonly CloudTable _table;\n        private readonly TimeSpan _ttl;\n        public const string UpdateSessionTableName = \"YamsUpdateSession\";\n        public const string UpdateDomainRowKey = \"updateDomain\";\n        public const string ModifiedRowKey = \"modified\";\n\n\n        /// <summary>\n        /// </summary>\n        /// <param name=\"connectionString\"></param>\n        /// <param name=\"ttl\">If an instance update session is older than ttl, it will be ignored. The goal of this parameter \n        /// is to avoid situations where an instance fails to end its update session and blocks the cluster.</param>\n        public UpdateSessionTable(string connectionString, TimeSpan ttl)\n        {\n            _ttl = ttl;\n            CloudTableClient client = CloudStorageAccount.Parse(connectionString).CreateCloudTableClient();\n            _table = client.GetTableReference(UpdateSessionTableName);\n            _table.CreateIfNotExists();\n        }\n\n        public Task<UpdateSessionStatus> FetchUpdateSessionStatus(string superClusterId)\n        {\n            string partitionQuery = CreatePartitionQuery(superClusterId);\n\n            TableQuery<UpdateDomainEntity> query = new TableQuery<UpdateDomainEntity>().Where(partitionQuery);\n            UpdateDomainEntity updateDomainEntity = null;\n            UpdateDomainEntity instanceListModifiedEntity = null;\n            Dictionary<string, List<UpdateDomainEntity>> instanceEntitiesDict = new Dictionary<string, List<UpdateDomainEntity>>();\n            foreach (UpdateDomainEntity entity in _table.ExecuteQuery(query))\n            {\n                if (entity.RowKey == UpdateDomainRowKey)\n                {\n                    updateDomainEntity = entity;\n                }\n                else if (entity.RowKey == ModifiedRowKey)\n                {\n                    instanceListModifiedEntity = entity;\n                }\n                else\n                {\n                    if (entity.Timestamp.Add(_ttl) > DateTimeOffset.Now)\n                    {\n                        AddInstanceEntity(instanceEntitiesDict, entity);\n                    }\n                }\n            }\n\n            List<UpdateDomainEntity> instancesEntities = null;\n            string updateDomain = updateDomainEntity?.UpdateDomain;\n            if (!string.IsNullOrWhiteSpace(updateDomain))\n            {\n                // filter out entities that do not match the active update domain (were leftover for some reason)\n                instanceEntitiesDict.TryGetValue(updateDomain, out instancesEntities);\n            }\n            if (instancesEntities == null)\n            {\n                instancesEntities = new List<UpdateDomainEntity>();\n            }\n\n            return Task.FromResult(new UpdateSessionStatus(instancesEntities, instanceListModifiedEntity, updateDomainEntity));\n        }\n\n        private static void AddInstanceEntity(Dictionary<string, List<UpdateDomainEntity>> instanceEntitiesDict, UpdateDomainEntity entity)\n        {\n            List<UpdateDomainEntity> instancesList;\n            if (instanceEntitiesDict.TryGetValue(entity.UpdateDomain, out instancesList))\n            {\n                instancesList.Add(entity);\n            } \n            else\n            {\n                instancesList = new List<UpdateDomainEntity>();\n                instancesList.Add(entity);\n                instanceEntitiesDict[entity.UpdateDomain] = instancesList;\n            }\n        }\n\n        public async Task<bool> TryExecuteTransaction(UpdateSessionTransaction transaction)\n        {\n            try\n            {\n                await _table.ExecuteBatchAsync(transaction.BatchOperation);\n\n                return true;\n            }\n            catch (StorageException e)\n            {\n                if (e.RequestInformation.HttpStatusCode != 412  // insert operation of an entity that already exists\n                    && e.RequestInformation.HttpStatusCode != 409 // optimistic concurrency conflict based on Etag\n                    )\n                {\n                    throw;\n                }\n            }\n            return false;\n        }\n\n        public async Task DeleteInstanceEntity(string superClusterId, string instanceId)\n        {\n            TableOperation retrieveOperation = TableOperation.Retrieve<UpdateDomainEntity>(superClusterId, \n                instanceId);\n            TableResult retrievedResult = await _table.ExecuteAsync(retrieveOperation);\n            var instanceEntity = (UpdateDomainEntity)retrievedResult.Result;\n            if (instanceEntity != null)\n            {\n                TableOperation deleteOperation = TableOperation.Delete(instanceEntity);\n                await _table.ExecuteAsync(deleteOperation);\n            }\n        }\n\n        public async Task<string> GetActiveUpdateDomain(string superClusterId)\n        {\n            TableOperation retrieveOperation = TableOperation.Retrieve<UpdateDomainEntity>(superClusterId, \n                UpdateDomainRowKey);\n\n            // Execute the retrieve operation.\n            TableResult retrievedResult = await _table.ExecuteAsync(retrieveOperation);\n\n            var entity = (UpdateDomainEntity)retrievedResult?.Result;\n            return entity?.UpdateDomain;\n        }\n\n        private static string CreatePartitionQuery(string superClusterId)\n        {\n            return TableQuery.GenerateFilterCondition(\"PartitionKey\", QueryComparisons.Equal,\n                superClusterId);\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/UpdateSession/UpdateSessionTransaction.cs",
    "content": "using Microsoft.WindowsAzure.Storage.Table;\n\nnamespace Etg.Yams.Azure.UpdateSession\n{\n    public class UpdateSessionTransaction\n    {\n        private readonly string _superClusterId;\n        private readonly string _instanceId;\n        private readonly string _updateDomain;\n        private readonly TableBatchOperation _batchOperation = new TableBatchOperation();\n\n        public UpdateSessionTransaction(string superClusterId, string instanceId, string updateDomain)\n        {\n            _superClusterId = superClusterId;\n            _instanceId = instanceId;\n            _updateDomain = updateDomain;\n        }\n\n        public UpdateSessionTransaction InsertUpdateDomain()\n        {\n            var updateDomainEntity = new UpdateDomainEntity(PartitionKey,\n                UpdateSessionTable.UpdateDomainRowKey, _updateDomain);\n            _batchOperation.Add(TableOperation.Insert(updateDomainEntity));\n            return this;\n        }\n\n        public UpdateSessionTransaction InsertOrReplaceInstance()\n        {\n            var instanceEntity = new UpdateDomainEntity(PartitionKey, _instanceId, _updateDomain);\n            _batchOperation.Add(TableOperation.InsertOrReplace(instanceEntity));\n\n            return this;\n        }\n\n        public UpdateSessionTransaction MarkInstanceListAsModified()\n        {\n            var modifiedEntity = new UpdateDomainEntity(PartitionKey, UpdateSessionTable.ModifiedRowKey, \"\");\n            _batchOperation.Add(TableOperation.InsertOrReplace(modifiedEntity));\n            return this;\n        }\n\n        public UpdateSessionTransaction FailIfInstanceListModified(UpdateSessionStatus status)\n        {\n            _batchOperation.Add(TableOperation.Replace(status.ModifiedEntity));\n            return this;\n        }\n\n        public UpdateSessionTransaction ReplaceUpdateDomain(UpdateSessionStatus status)\n        {\n            var updateDomainEntity = status.UpdateDomainEntity;\n            updateDomainEntity.UpdateDomain = _updateDomain;\n            _batchOperation.Add(TableOperation.Replace(updateDomainEntity));\n\n            return this;\n        }\n\n        public TableBatchOperation BatchOperation => _batchOperation;\n\n        private string PartitionKey => _superClusterId;\n    }\n}"
  },
  {
    "path": "src/AzureBlobStorageUpdateSession/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net451\" />\n  <package id=\"EnterpriseLibrary.TransientFaultHandling\" version=\"6.0.1304.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "src/AzureBlobUtils/AzureBlobUtils.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{5887E0F7-9497-4798-AB98-6C4209AEA35E}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Azure</RootNamespace>\n    <AssemblyName>AzureBlobUtils</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.6.4\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.6.4\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.6.4\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=6.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.6.2.0\\lib\\net40\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.6.4\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"BlobUtils.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "src/AzureBlobUtils/BlobUtils.cs",
    "content": "using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Etg.Yams.Utils;\nusing Microsoft.WindowsAzure.Storage;\nusing Microsoft.WindowsAzure.Storage.Blob;\n\nnamespace Etg.Yams.Azure\n{\n    public static class BlobUtils\n    {\n        public static Task DownloadBlobDirectory(CloudBlobDirectory blobDirectory, string destPath)\n        {\n            return DownloadBlobs((dynamic) blobDirectory, destPath);\n        }\n\n        public static Task DownloadBlobContainer(CloudBlobContainer blobContainer, string destPath)\n        {\n            return DownloadBlobs((dynamic) blobContainer, destPath);\n        }\n\n        private static async Task DownloadBlobs(dynamic blobDirectory, string destPath)\n        {\n            await FileUtils.DeleteDirectoryIfAny(destPath);\n            await FileUtils.CreateDirectory(destPath);\n\n            IEnumerable<IListBlobItem> blobs = await ListBlobsFlat(blobDirectory);\n            var tasks = new List<Task>();\n            foreach (var blobItem in blobs)\n            {\n                var blob = (CloudBlockBlob) blobItem;\n                await blob.FetchAttributesAsync();\n                var localPathBlob = Path.Combine(destPath, GetLocalRelativePath(blob, blobDirectory));\n                string dirPath = Path.GetDirectoryName(localPathBlob);\n                if (!Directory.Exists(dirPath))\n                {\n                    Directory.CreateDirectory(dirPath);\n                }\n                tasks.Add(blob.DownloadToFileAsync(localPathBlob, FileMode.Create));\n            }\n            await Task.WhenAll(tasks);\n        }\n\n        private static Task<IEnumerable<IListBlobItem>> ListBlobsFlat(dynamic blobDirectory,\n            bool useFlatBlobListing = true)\n        {\n            return Task.Run(() => (IEnumerable<IListBlobItem>) blobDirectory.ListBlobs(useFlatBlobListing));\n        }\n\n        public static Task<IEnumerable<IListBlobItem>> ListBlobsAsync(this CloudBlobDirectory blobDirectory,\n            bool useFlatBlobListing = true)\n        {\n            return ListBlobsFlat(blobDirectory, useFlatBlobListing);\n        }\n\n\n        private static string GetLocalRelativePath(ICloudBlob blob, dynamic blobDirectory)\n        {\n            return GetBlobRelativePath(blob, blobDirectory).Replace('/', '\\\\');\n        }\n\n        private static string GetBlobRelativePathInternal(ICloudBlob blob, dynamic parentDirectory)\n        {\n            return blob.Uri.LocalPath.Remove(0, parentDirectory.Uri.LocalPath.Length).TrimStart('/');\n        }\n\n        public static string GetBlobRelativePath(ICloudBlob blob, CloudBlobDirectory parentDirectory)\n        {\n            return GetBlobRelativePathInternal(blob, parentDirectory);\n        }\n\n        public static string GetBlobRelativePath(ICloudBlob blob, CloudBlobContainer container)\n        {\n            return GetBlobRelativePathInternal(blob, container);\n        }\n\n        public static async Task CreateEmptyBlob(ICloudBlob blob)\n        {\n            var emptyByteArray = new byte[] {};\n            await blob.UploadFromByteArrayAsync(emptyByteArray, 0, emptyByteArray.Length);\n            await blob.FetchAttributesAsync();\n        }\n\n        public static Task UploadFile(string localPath, CloudBlobContainer blobContainer, string blobPath)\n        {\n            CloudBlockBlob blob = blobContainer.GetBlockBlobReference(blobPath);\n            return blob.UploadFromFileAsync(localPath, FileMode.Open);\n        }\n\n        public static Task UploadDirectory(string localDirPath, CloudBlobContainer blobContainer, string blobDirPath)\n        {\n            var tasks = new List<Task>();\n            foreach (string filePath in FileUtils.ListFilesRecursively(localDirPath))\n            {\n                string relPath = FileUtils.GetRelativePath(localDirPath, filePath);\n                string blobPath = Path.Combine(blobDirPath, relPath).Replace('\\\\', '/');\n                tasks.Add(UploadFile(filePath, blobContainer, blobPath));\n            }\n            return Task.WhenAll(tasks);\n        }\n\n        public static CloudBlobContainer GetBlobContainer(string connectionString, string containerName)\n        {\n            CloudStorageAccount account = CloudStorageAccount.Parse(connectionString);\n            CloudBlobClient blobClient = account.CreateCloudBlobClient();\n            return blobClient.GetContainerReference(containerName);\n        }\n\n        public static Task<bool> ExistsAsync(this CloudBlobDirectory dir)\n        {\n            return Task.Run(() => dir.ListBlobs().Any());\n        }\n\n        public static Task DeleteAsync(this CloudBlobDirectory dir)\n        {\n            return Task.Run(() =>\n            {\n                IEnumerable<IListBlobItem> blobs = dir.ListBlobs(true);\n                var tasks = new List<Task>();\n                foreach (IListBlobItem blobItem in blobs)\n                {\n                    CloudBlockBlob blob = (CloudBlockBlob) blobItem;\n                    tasks.Add(blob.DeleteAsync());\n                }\n                return Task.WhenAll(tasks);\n            });\n        }\n    }\n}"
  },
  {
    "path": "src/AzureBlobUtils/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"AzureBlobUtils\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"AzureBlobUtils\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"5887e0f7-9497-4798-ab98-6c4209aea35e\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/AzureBlobUtils/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.6.4\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.6.4\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.6.4\" targetFramework=\"net45\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net45\" />\n  <package id=\"System.Spatial\" version=\"5.6.4\" targetFramework=\"net45\" />\n  <package id=\"WindowsAzure.Storage\" version=\"6.2.0\" targetFramework=\"net45\" />\n</packages>"
  },
  {
    "path": "src/AzureUtils/AzureUtils.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{1C890E49-5A9B-4EAB-9F69-6A6E78D82610}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Azure</RootNamespace>\n    <AssemblyName>Etg.Yams.AzureUtils</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Reactive.Core, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Reactive.Core.3.1.1\\lib\\net45\\System.Reactive.Core.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Reactive.Interfaces, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Reactive.Interfaces.3.1.1\\lib\\net45\\System.Reactive.Interfaces.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Reactive.Linq, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Reactive.Linq.3.1.1\\lib\\net45\\System.Reactive.Linq.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Reactive.PlatformServices, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Reactive.PlatformServices.3.1.1\\lib\\net45\\System.Reactive.PlatformServices.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Reactive.Windows.Threading.3.1.1\\lib\\net45\\System.Reactive.Windows.Threading.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Windows\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n    <Reference Include=\"WindowsBase\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Lease\\BlobLeaseFactory.cs\" />\n    <Compile Include=\"Lease\\IBlobLease.cs\" />\n    <Compile Include=\"Lease\\IBlobLeaseFactory.cs\" />\n    <Compile Include=\"Lease\\SelfRenewableBlobLease.cs\" />\n    <Compile Include=\"Utils\\BlobUtils.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Common\\Common.csproj\">\n      <Project>{3E982150-5B43-44DA-8D96-66CF07A9A14C}</Project>\n      <Name>Common</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "src/AzureUtils/Lease/BlobLeaseFactory.cs",
    "content": "﻿using Microsoft.WindowsAzure.Storage.Blob;\n\nnamespace Etg.Yams.Azure.Lease\n{\n    public class BlobLeaseFactory : IBlobLeaseFactory\n    {\n        public IBlobLease CreateLease(ICloudBlob blob)\n        {\n            return new SelfRenewableBlobLease(blob);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AzureUtils/Lease/IBlobLease.cs",
    "content": "using System;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Azure.Lease\n{\n    public interface IBlobLease : IDisposable\n    {\n        /// <summary>\n        /// </summary>\n        /// <returns>The leaseId if the lease is successfully acquired, null otherwise</returns>\n        Task<string> TryAcquireLease();\n\n        Task ReleaseLease();\n    }\n}"
  },
  {
    "path": "src/AzureUtils/Lease/IBlobLeaseFactory.cs",
    "content": "﻿using Microsoft.WindowsAzure.Storage.Blob;\n\nnamespace Etg.Yams.Azure.Lease\n{\n    public interface IBlobLeaseFactory\n    {\n        IBlobLease CreateLease(ICloudBlob blob);\n    }\n}\n"
  },
  {
    "path": "src/AzureUtils/Lease/SelfRenewableBlobLease.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Reactive.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.WindowsAzure.Storage;\nusing Microsoft.WindowsAzure.Storage.Blob;\n\nnamespace Etg.Yams.Azure.Lease\n{\n    /// <summary>\n    /// A lease that doesn't expire.\n    /// TODO: Investigate if an alternative exists in Azure and get rid of this class if possible.\n    /// </summary>\n    public class SelfRenewableBlobLease : IBlobLease\n    {\n        private string _leaseId;\n        private readonly int _renewIntervalInSeconds;\n        private readonly ICloudBlob _blob;\n\n        private IDisposable KeepAliveRxTimer { get; set; }\n\n        public SelfRenewableBlobLease(ICloudBlob blob)\n        {\n            _renewIntervalInSeconds = 60;\n            _blob = blob;\n        }\n\n        public async Task<string> TryAcquireLease()\n        {\n            try\n            {\n                var leaseTime = TimeSpan.FromSeconds(_renewIntervalInSeconds);\n                _leaseId = await _blob.AcquireLeaseAsync(leaseTime, null);\n                KeepAliveRxTimer = Observable.Interval(TimeSpan.FromSeconds(_renewIntervalInSeconds - 9.0)).Subscribe(async l => await RenewLease(_blob, _leaseId));\n            }\n            catch (StorageException ex)\n            {\n                _leaseId = null;\n                Trace.TraceInformation(string.Format(\"Failed to acquire the lease on blob {0}\", _blob), ex);\n            }\n            if (_leaseId == null)\n            {\n                await DisableTimer();\n            }\n            return _leaseId;\n        }\n\n        private Task DisableTimer()\n        {\n            return Task.Run(() =>\n            {\n                if (KeepAliveRxTimer != null)\n                {\n                    KeepAliveRxTimer.Dispose();\n                }\n            });\n        }\n\n\n        public async Task ReleaseLease()\n        {\n            await DisableTimer();\n            if (_leaseId == null)\n            {\n                Trace.TraceWarning(\"Attempt to release a blob that is not locked.. will ignore\");\n                return;\n            }\n            \n            try\n            {\n                await _blob.ReleaseLeaseAsync(\n                    new AccessCondition\n                    {\n                        LeaseId = _leaseId\n                    });\n                _leaseId = null;\n            }\n            catch (StorageException ex)\n            {\n                Trace.TraceError(\"Failed to release lease on blob {0} using lease id {1}. Exception was: {2}\", _blob.Name, _leaseId, ex);\n            }\n        }\n\n        private static async Task RenewLease(ICloudBlob blob, string leaseId)\n        {\n            var blobKey = GetKey(blob);\n            try\n            {\n                await blob.RenewLeaseAsync(\n                    new AccessCondition\n                    {\n                        LeaseId = leaseId\n                    });\n                Trace.TraceInformation(\"Renewed lease for blob {0}\", blobKey);\n            }\n            catch (Exception ex)\n            {\n                Trace.TraceError(\"Failed to renew lease for blob {0}. Exception was: {1}\", blobKey, ex);\n            }\n        }\n\n        private static string GetKey(ICloudBlob blob)\n        {\n            return blob.Container.Name + \"-\" + blob.Name;\n        }\n\n        public void Dispose()\n        {\n            if (_leaseId != null)\n            {\n                ReleaseLease().Wait();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/AzureUtils/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"AzureUtils\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"AzureUtils\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"1c890e49-5a9b-4eab-9f69-6a6e78d82610\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/AzureUtils/Utils/BlobUtils.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Security.Cryptography;\nusing System.Threading.Tasks;\nusing Etg.Yams.Utils;\nusing Microsoft.WindowsAzure.Storage;\nusing Microsoft.WindowsAzure.Storage.Blob;\n\nnamespace Etg.Yams.Azure.Utils\n{\n    public static class BlobUtils\n    {\n        public static async Task DownloadBlobDirectory(CloudBlobDirectory blobDirectory, string destPath)\n        {\n            if (!Directory.Exists(destPath))\n            {\n                await FileUtils.CreateDirectory(destPath);\n            }\n\n            IEnumerable<IListBlobItem> blobs = await ListBlobsFlat(blobDirectory);\n            var tasks = new List<Task>();\n\n            using (var md5 = new MD5CryptoServiceProvider())\n            {\n                foreach (var blobItem in blobs)\n                {\n                    var blob = (CloudBlockBlob)blobItem;\n                    await blob.FetchAttributesAsync();\n                    string relativePath = GetLocalRelativePath(blob, blobDirectory);\n                    var localFilePath = Path.Combine(destPath, relativePath);\n                    string dirPath = Path.GetDirectoryName(localFilePath);\n                    if (!Directory.Exists(dirPath))\n                    {\n                        Directory.CreateDirectory(dirPath);\n                    }\n                    if (File.Exists(localFilePath))\n                    {\n                        string hash = ComputeMd5Hash(md5, localFilePath);\n                        if (hash == blob.Properties.ContentMD5)\n                        {\n                            continue;\n                        }\n                    }\n                    tasks.Add(blob.DownloadToFileAsync(localFilePath, FileMode.Create));\n                }\n            }\n            await Task.WhenAll(tasks);\n        }\n\n        private static string ComputeMd5Hash(MD5CryptoServiceProvider md5, string localFilePath)\n        {\n            using (var stream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read))\n            {\n                return Convert.ToBase64String(md5.ComputeHash(stream));\n            }\n        }\n\n        private static Task<IEnumerable<IListBlobItem>> ListBlobsFlat(dynamic blobDirectory,\n            bool useFlatBlobListing = true)\n        {\n            return Task.Run(() => (IEnumerable<IListBlobItem>) blobDirectory.ListBlobs(useFlatBlobListing));\n        }\n\n        public static Task<IEnumerable<IListBlobItem>> ListBlobsAsync(this CloudBlobDirectory blobDirectory,\n            bool useFlatBlobListing = true)\n        {\n            return ListBlobsFlat(blobDirectory, useFlatBlobListing);\n        }\n\n        private static string GetLocalRelativePath(ICloudBlob blob, dynamic blobDirectory)\n        {\n            return GetBlobRelativePath(blob, blobDirectory).Replace('/', '\\\\');\n        }\n\n        private static string GetBlobRelativePathInternal(ICloudBlob blob, dynamic parentDirectory)\n        {\n            return blob.Uri.LocalPath.Remove(0, parentDirectory.Uri.LocalPath.Length).TrimStart('/');\n        }\n\n        public static string GetBlobRelativePath(ICloudBlob blob, CloudBlobDirectory parentDirectory)\n        {\n            return GetBlobRelativePathInternal(blob, parentDirectory);\n        }\n\n        public static string GetBlobRelativePath(ICloudBlob blob, CloudBlobContainer container)\n        {\n            return GetBlobRelativePathInternal(blob, container);\n        }\n\n        public static async Task CreateBlobIfNotExists(ICloudBlob blob)\n        {\n            var emptyByteArray = new byte[] { };\n            try\n            {\n                await blob.UploadFromByteArrayAsync(emptyByteArray, 0, emptyByteArray.Length,\n                    AccessCondition.GenerateIfNotExistsCondition(), new BlobRequestOptions(), new OperationContext());\n            } catch(StorageException e)\n            {\n                if(e.RequestInformation.HttpStatusCode != 409)\n                {\n                    throw;\n                }\n            }\n        }\n\n        public static async Task CreateEmptyBlob(ICloudBlob blob)\n        {\n            var emptyByteArray = new byte[] {};\n            await blob.UploadFromByteArrayAsync(emptyByteArray, 0, emptyByteArray.Length);\n            await blob.FetchAttributesAsync();\n        }\n\n        public static Task UploadFile(string localPath, CloudBlobContainer blobContainer, string blobPath)\n        {\n            CloudBlockBlob blob = blobContainer.GetBlockBlobReference(blobPath);\n            return blob.UploadFromFileAsync(localPath);\n        }\n\n        public static Task UploadDirectory(string localDirPath, CloudBlobContainer blobContainer, string blobDirPath)\n        {\n            var tasks = new List<Task>();\n            foreach (string filePath in FileUtils.ListFilesRecursively(localDirPath))\n            {\n                string relPath = FileUtils.GetRelativePath(localDirPath, filePath);\n                string blobPath = Path.Combine(blobDirPath, relPath).Replace('\\\\', '/');\n                tasks.Add(UploadFile(filePath, blobContainer, blobPath));\n            }\n            return Task.WhenAll(tasks);\n        }\n\n        public static CloudBlobContainer GetBlobContainer(string connectionString, string containerName)\n        {\n            CloudStorageAccount account = CloudStorageAccount.Parse(connectionString);\n            CloudBlobClient blobClient = account.CreateCloudBlobClient();\n            var blobContainer = blobClient.GetContainerReference(containerName);\n            if (!blobContainer.Exists())\n            {\n                blobContainer.Create();\n            }\n            return blobContainer;\n        }\n\n        public static async Task<bool> ExistsAsync(this CloudBlobDirectory dir)\n        {\n            return (await dir.ListBlobsAsync()).Any();\n        }\n\n        public static async Task DeleteAsync(this CloudBlobDirectory dir)\n        {\n            IEnumerable<IListBlobItem> blobs = await dir.ListBlobsAsync(useFlatBlobListing:true);\n            var tasks = new List<Task>();\n            foreach (IListBlobItem blobItem in blobs)\n            {\n                CloudBlockBlob blob = (CloudBlockBlob) blobItem;\n                tasks.Add(blob.DeleteAsync());\n            }\n            await Task.WhenAll(tasks);\n        }\n    }\n}"
  },
  {
    "path": "src/AzureUtils/app.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n    </assemblyBinding>\n  </runtime>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\"/></startup></configuration>\n"
  },
  {
    "path": "src/AzureUtils/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Reactive\" version=\"3.1.1\" targetFramework=\"net451\" />\n  <package id=\"System.Reactive.Core\" version=\"3.1.1\" targetFramework=\"net451\" />\n  <package id=\"System.Reactive.Interfaces\" version=\"3.1.1\" targetFramework=\"net451\" />\n  <package id=\"System.Reactive.Linq\" version=\"3.1.1\" targetFramework=\"net451\" />\n  <package id=\"System.Reactive.PlatformServices\" version=\"3.1.1\" targetFramework=\"net451\" />\n  <package id=\"System.Reactive.Windows.Threading\" version=\"3.1.1\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "src/Common/Common.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{3E982150-5B43-44DA-8D96-66CF07A9A14C}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams</RootNamespace>\n    <AssemblyName>Etg.Yams.Common</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Json\\IJsonSerializer.cs\" />\n    <Compile Include=\"Json\\JsonSerializer.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Utils\\DictionaryUtils.cs\" />\n    <Compile Include=\"Utils\\FileUtils.cs\" />\n    <Compile Include=\"Utils\\HashCodeUtils.cs\" />\n    <Compile Include=\"Utils\\TaskExtensions.cs\" />\n    <Compile Include=\"Utils\\TraceUtils.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "src/Common/FileUtils.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Utils\n{\n    public static class FileUtils\n    {\n        public static Task CopyDir(string srcPath, string destPath, bool overwrite)\n        {\n            return Task.Run(() =>\n            {\n                if (!Directory.Exists(destPath))\n                {\n                    Directory.CreateDirectory(destPath);\n                }\n                foreach (string dirPath in Directory.GetDirectories(srcPath, \"*\",\n                    SearchOption.AllDirectories))\n                    Directory.CreateDirectory(dirPath.Replace(srcPath, destPath));\n\n                foreach (string newPath in Directory.GetFiles(srcPath, \"*.*\",\n                    SearchOption.AllDirectories))\n                    File.Copy(newPath, newPath.Replace(srcPath, destPath), overwrite);\n            });\n        }\n\n        public static Task CreateDirectory(string path)\n        {\n            return Task.Run(() => { Directory.CreateDirectory(path); });\n        }\n\n        public static Task DeleteDirectoryIfAny(string destPath, bool recursive = true)\n        {\n            return Task.Run(() =>\n            {\n                if (Directory.Exists(destPath))\n                {\n                    Directory.Delete(destPath, recursive);\n                }\n            });\n        }\n\n        public static IEnumerable<string> ListFilesRecursively(string dirPath)\n        {\n            var dirQueue = new Queue<string>();\n            dirQueue.Enqueue(dirPath);\n\n            while (dirQueue.Count > 0)\n            {\n                string currentFolder = dirQueue.Dequeue();\n                foreach (string subFolder in Directory.GetDirectories(currentFolder))\n                {\n                    dirQueue.Enqueue(subFolder);\n                }\n\n                foreach (string filePath in Directory.GetFiles(currentFolder))\n                {\n                    yield return filePath;\n                }\n            }\n        }\n\n        public static string GetRelativePath(string dirPath, string filePath)\n        {\n            string path = filePath.Remove(0, dirPath.Length);\n            if (path.StartsWith(\"\\\\\"))\n            {\n                path = path.Remove(0, 1);\n            }\n            return path;\n        }\n\n        public static bool DirectoryDoesntExistOrEmpty(string path)\n        {\n            return !Directory.Exists(path) || !ListFilesRecursively(path).Any();\n        }\n    }\n}"
  },
  {
    "path": "src/Common/Json/IJsonSerializer.cs",
    "content": "using System.Threading.Tasks;\n\nnamespace Etg.Yams.Json\n{\n    public interface IJsonSerializer\n    {\n        string Serialize(object data);\n        Task SerializeAsync(object data);\n        T Deserialize<T>(string data);\n        Task<T> DeserializeAsync<T>(string data);\n    }\n}"
  },
  {
    "path": "src/Common/Json/JsonSerializer.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Serialization;\n\nnamespace Etg.Yams.Json\n{\n    public class JsonSerializer : IJsonSerializer\n    {\n        private readonly ITraceWriter _traceWriter;\n\n        public JsonSerializer(ITraceWriter traceWriter)\n        {\n            _traceWriter = traceWriter;\n        }\n\n        public Task<T> DeserializeAsync<T>(string data)\n        {\n            return Task.Run(() => Deserialize<T>(data));\n        }\n\n        public Task SerializeAsync(object data)\n        {\n            return Task.Run(() => Serialize(data));\n        }\n\n        public T Deserialize<T>(string data)\n        {\n            return JsonConvert.DeserializeObject<T>(data, new JsonSerializerSettings\n            {\n                TraceWriter = _traceWriter\n            });\n        }\n\n        public string Serialize(object data)\n        {\n            return JsonConvert.SerializeObject(data, Formatting.Indented, new JsonSerializerSettings\n            {\n                TraceWriter = _traceWriter\n            });\n        }\n    }\n}"
  },
  {
    "path": "src/Common/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Common\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Common\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"3e982150-5b43-44da-8d96-66cf07a9a14c\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/Common/Utils/DictionaryUtils.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\n\nnamespace Etg.Yams.Utils\n{\n    public static class DictionaryUtils\n    {\n        public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(IReadOnlyDictionary<TKey, TValue> roDictionary)\n        {\n            return roDictionary.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);\n        }\n    }\n}"
  },
  {
    "path": "src/Common/Utils/FileUtils.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Utils\n{\n    public static class FileUtils\n    {\n        public static Task CopyDir(string srcPath, string destPath, bool overwrite)\n        {\n            return Task.Run(() =>\n            {\n                if (!Directory.Exists(destPath))\n                {\n                    Directory.CreateDirectory(destPath);\n                }\n                foreach (string dirPath in Directory.GetDirectories(srcPath, \"*\",\n                    SearchOption.AllDirectories))\n                    Directory.CreateDirectory(dirPath.Replace(srcPath, destPath));\n\n                foreach (string newPath in Directory.GetFiles(srcPath, \"*.*\",\n                    SearchOption.AllDirectories))\n                    File.Copy(newPath, newPath.Replace(srcPath, destPath), overwrite);\n            });\n        }\n\n        public static Task CreateDirectory(string path)\n        {\n            return Task.Run(() => { Directory.CreateDirectory(path); });\n        }\n\n        public static Task DeleteDirectoryIfAny(string destPath, bool recursive = true)\n        {\n            return Task.Run(() =>\n            {\n                if (Directory.Exists(destPath))\n                {\n                    Directory.Delete(destPath, recursive);\n                }\n            });\n        }\n\n        public static IEnumerable<string> ListFilesRecursively(string dirPath)\n        {\n            var dirQueue = new Queue<string>();\n            dirQueue.Enqueue(dirPath);\n\n            while (dirQueue.Count > 0)\n            {\n                string currentFolder = dirQueue.Dequeue();\n                foreach (string subFolder in Directory.GetDirectories(currentFolder))\n                {\n                    dirQueue.Enqueue(subFolder);\n                }\n\n                foreach (string filePath in Directory.GetFiles(currentFolder))\n                {\n                    yield return filePath;\n                }\n            }\n        }\n\n        public static string GetRelativePath(string dirPath, string filePath)\n        {\n            string path = filePath.Remove(0, dirPath.Length);\n            if (path.StartsWith(\"\\\\\"))\n            {\n                path = path.Remove(0, 1);\n            }\n            return path;\n        }\n\n        public static bool DirectoryDoesntExistOrEmpty(string path)\n        {\n            return !Directory.Exists(path) || !ListFilesRecursively(path).Any();\n        }\n    }\n}"
  },
  {
    "path": "src/Common/Utils/HashCodeUtils.cs",
    "content": "using System.Collections;\n\nnamespace Etg.Yams.Utils\n{\n    public static class HashCodeUtils\n    {\n        public static int GetHashCode(IEnumerable enumerable)\n        {\n            unchecked\n            {\n                int hash = 19;\n                foreach (var element in enumerable)\n                {\n                    hash = (hash*31) ^ element.GetHashCode();\n                }\n                return hash;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/Common/Utils/TaskExtensions.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Utils\n{\n    public static class TaskExtensions\n    {\n        public static async Task Timeout(this Task task, TimeSpan timeout, string timeoutMessage=\"\")\n        {\n            var timeoutCancellationTokenSource = new CancellationTokenSource();\n\n            var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token));\n            if (completedTask == task)\n            {\n                timeoutCancellationTokenSource.Cancel();\n                await task;\n            }\n            else\n            {\n                throw new TimeoutException(timeoutMessage);\n            }\n        }\n\n        public static async Task<TResult> Timeout<TResult>(this Task<TResult> task, TimeSpan timeout, string timeoutMessage = \"\")\n        {\n\n            var timeoutCancellationTokenSource = new CancellationTokenSource();\n\n            var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token));\n            if (completedTask == task)\n            {\n                timeoutCancellationTokenSource.Cancel();\n                return await task;\n            }\n            throw new TimeoutException(timeoutMessage);\n        }\n    }\n}"
  },
  {
    "path": "src/Common/Utils/TraceUtils.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\n\nnamespace Etg.Yams.Utils\n{\n    public static class TraceUtils\n    {\n        public static void TraceAllErrors(string msg, AggregateException aggregateException)\n        {\n            foreach (Exception innerException in aggregateException.InnerExceptions)\n            {\n                Trace.TraceError(\"{0} Exception: {1}\", msg, innerException);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Common/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "src/Etg.Yams/Etg.Yams.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Release</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{E1A6854F-6C0D-4F93-9B8D-D6981727D15B}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams</RootNamespace>\n    <AssemblyName>Etg.Yams</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"YamsServiceFactory.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"Etg.Yams.nuspec\">\n      <SubType>Designer</SubType>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\AzureBlobStorageDeploymentRepository\\AzureBlobStorageDeploymentRepository.csproj\">\n      <Project>{df95a9dc-f6be-4c71-b444-4092b43eb602}</Project>\n      <Name>AzureBlobStorageDeploymentRepository</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\AzureBlobStorageUpdateSession\\AzureBlobStorageUpdateSession.csproj\">\n      <Project>{894b7986-5aa4-42a7-8eb0-6dfd1f604505}</Project>\n      <Name>AzureBlobStorageUpdateSession</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Common\\Common.csproj\">\n      <Project>{3e982150-5b43-44da-8d96-66cf07a9a14c}</Project>\n      <Name>Common</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Etg.Yams.Core\\Etg.Yams.Core.csproj\">\n      <Project>{7145e485-34fa-4632-89b0-bd27c96af69c}</Project>\n      <Name>Etg.Yams.Core</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "src/Etg.Yams/Etg.Yams.nuspec",
    "content": "<?xml version=\"1.0\"?>\n<package >\n  <metadata>\n    <id>Etg.Yams</id>\n    <version>1.8.3</version>\n    <title>YAMS</title>\n    <authors>Microsoft Studios (BigPark)</authors>\n    <owners>Microsoft Studios (BigPark)</owners>\n    <licenseUrl>https://opensource.org/licenses/MIT</licenseUrl>\n\t<projectUrl>https://github.com/Microsoft/Yams</projectUrl>\n    <requireLicenseAcceptance>false</requireLicenseAcceptance>\n    <description>YAMS is a framework for deploying and hosting microservices that allows quick deployments of Azure services (~1 minute), sharing infrastructure (multiple services on the same VM), versioning and more.</description>\n    <copyright>Copyright (c) Microsoft Corporation</copyright>\n  </metadata>\n</package>"
  },
  {
    "path": "src/Etg.Yams/NuGetPack.bat",
    "content": "nuget pack Etg.Yams.csproj -IncludeReferencedProjects -Prop Configuration=Release"
  },
  {
    "path": "src/Etg.Yams/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Etg.Yams\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Etg.Yams\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2015\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"dfe42f8c-e322-4f6e-8b2c-bebe507cc0bb\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/Etg.Yams/YamsServiceFactory.cs",
    "content": "﻿using Etg.Yams.Azure.Storage;\nusing Etg.Yams.Azure.UpdateSession;\nusing Etg.Yams.Update;\n\nnamespace Etg.Yams\n{\n    public class YamsServiceFactory\n    {\n        public static IYamsService Create(YamsConfig yamsConfig, string deploymentRepositoryStorageConnectionString,\n            string updateSessionStorageConnectionString)\n        {\n            IUpdateSessionManager updateSessionManager = new AzureStorageUpdateSessionDiModule(\n                yamsConfig.SuperClusterId,\n                yamsConfig.ClusterId,\n                yamsConfig.InstanceId,\n                yamsConfig.InstanceUpdateDomain,\n                updateSessionStorageConnectionString,\n                yamsConfig.UpdateSessionTtl).UpdateSessionManager;\n\n            var deploymentRepository = BlobStorageDeploymentRepository.Create(deploymentRepositoryStorageConnectionString);\n            return new YamsDiModule(yamsConfig, deploymentRepository, deploymentRepository, updateSessionManager).YamsService;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n    </assemblyBinding>\n  </runtime>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" /></startup></configuration>\n"
  },
  {
    "path": "src/Etg.Yams/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "src/Etg.Yams.Client/Etg.Yams.Client.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{D4624B9B-67A1-46D5-9468-58995B2720F9}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Client</RootNamespace>\n    <AssemblyName>Etg.Yams.Client</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\CommandLineParser.1.9.71\\lib\\net45\\CommandLine.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"IProcessArgsParser.cs\" />\n    <Compile Include=\"IYamsClient.cs\" />\n    <Compile Include=\"IYamsClientFactory.cs\" />\n    <Compile Include=\"ProcessArgsParser.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"YamsClient.cs\" />\n    <Compile Include=\"YamsClientConfig.cs\" />\n    <Compile Include=\"YamsClientConfigBuilder.cs\" />\n    <Compile Include=\"YamsClientFactory.cs\" />\n    <Compile Include=\"YamsClientOptions.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Etg.Yams.Client.nuspec\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Common\\Common.csproj\">\n      <Project>{3E982150-5B43-44DA-8D96-66CF07A9A14C}</Project>\n      <Name>Common</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Etg.Yams.Ipc\\Etg.Yams.Ipc.csproj\">\n      <Project>{c7c03d37-f2d2-4115-8423-86c1bf1b8a18}</Project>\n      <Name>Etg.Yams.Ipc</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n</Project>"
  },
  {
    "path": "src/Etg.Yams.Client/Etg.Yams.Client.nuspec",
    "content": "<?xml version=\"1.0\"?>\n<package >\n  <metadata>\n    <id>Etg.Yams.Client</id>\n    <version>1.1.0</version>\n    <title>YAMS Client</title>\n    <authors>Microsoft</authors>\n    <owners>Microsoft</owners>\n    <licenseUrl>https://opensource.org/licenses/MIT</licenseUrl>\n\t<projectUrl>https://github.com/Microsoft/Yams</projectUrl>\n    <requireLicenseAcceptance>false</requireLicenseAcceptance>\n    <description>YAMS Client can be used by YAMS application to take advantage of health monitoring and graceful shutdown features.</description>\n    <copyright>Copyright (c) Microsoft Corporation</copyright>\n  </metadata>\n</package>"
  },
  {
    "path": "src/Etg.Yams.Client/IProcessArgsParser.cs",
    "content": "namespace Etg.Yams.Client\n{\n    public interface IProcessArgsParser\n    {\n        YamsClientOptions ParseArgs(string[] args);\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Client/IYamsClient.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Client\n{\n    public interface IYamsClient : IDisposable\n    {\n        Task Connect();\n        Task SendHeartBeat();\n        Task SendInitializationDoneMessage();\n        event EventHandler ExitMessageReceived;\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Client/IYamsClientFactory.cs",
    "content": "﻿namespace Etg.Yams.Client\n{\n    public interface IYamsClientFactory\n    {\n        IYamsClient CreateYamsClient(YamsClientConfig config);\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Client/NuGetPack.bat",
    "content": "nuget pack Etg.Yams.Client.csproj -IncludeReferencedProjects -Prop Configuration=Release"
  },
  {
    "path": "src/Etg.Yams.Client/ProcessArgsParser.cs",
    "content": "using CommandLine;\n\nnamespace Etg.Yams.Client\n{\n    public class ProcessArgsParser : IProcessArgsParser\n    {\n        public YamsClientOptions ParseArgs(string[] args)\n        {\n            var options = new YamsClientOptions();\n            Parser.Default.ParseArguments(args, options);\n            return options;\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Client/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Etg.Yams.Client\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Etg.Yams.Client\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2017\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible\n// to COM components.  If you need to access a type in this assembly from\n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"d4624b9b-67a1-46d5-9468-58995b2720f9\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers\n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/Etg.Yams.Client/YamsClient.cs",
    "content": "﻿using Etg.Yams.Ipc;\nusing Etg.Yams.Utils;\nusing System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Client\n{\n    public class YamsClient : IYamsClient\n    {\n        private readonly YamsClientOptions _options;\n        private readonly YamsClientConfig _config;\n        private readonly IIpcConnection _initConnection;\n        private readonly IIpcConnection _exitConnection;\n        private readonly IIpcConnection _healthConnection;\n        private Task _waitForExit;\n\n        public event EventHandler ExitMessageReceived;\n\n        public YamsClient(YamsClientOptions options, YamsClientConfig config, IIpcConnection initConnection, IIpcConnection exitConnection,\n            IIpcConnection healthConnection)\n        {\n            _options = options;\n            _config = config;\n            _initConnection = initConnection;\n            _exitConnection = exitConnection;\n            _healthConnection = healthConnection;\n        }\n\n        public async Task Connect()\n        {\n            Trace.TraceInformation(FormatMessage($\"Connecting IPC connections..\"));\n            if (_initConnection != null)\n            {\n                await _initConnection.Connect().Timeout(_config.ConnectTimeout, FormatMessage(\"IPC Monitored Initialization connection failed to connect\"));\n                Trace.TraceInformation(FormatMessage(\"IPC Monitored Initialization connection connected!\"));\n            }\n            if(_exitConnection != null)\n            {\n                await _exitConnection.Connect().Timeout(_config.ConnectTimeout, FormatMessage(\"IPC Graceful Shutdown connection failed to connect\"));\n                Trace.TraceInformation(FormatMessage(\"IPC Graceful Shutdown connection connected!\"));\n            }\n            if (_healthConnection != null)\n            {\n                await _healthConnection.Connect().Timeout(_config.ConnectTimeout, FormatMessage(\"IPC Health connection failed to connect\"));\n                Trace.TraceInformation(FormatMessage(\"IPC Health connection connected!\"));\n            }\n            _waitForExit = WaitForExit();\n        }\n\n        public async Task SendInitializationDoneMessage()\n        {\n            if (_initConnection == null)\n            {\n                Trace.TraceError(\n                    FormatMessage(\"Initialization monitoring is not supported for this app. Check your AppConfig.json file\"));\n                return;\n            }\n            Trace.TraceInformation(FormatMessage(\"Sending Initialization message to Yams..\"));\n            await _initConnection.SendMessage(\"[INITIALIZE_DONE]\")\n                .Timeout(_config.InitDoneMessageTimeout, FormatMessage(\"Sending initialization message to Yams has timed out\"));\n            Trace.TraceInformation(FormatMessage(\"Initialization message has been sent to Yams successfully!\"));\n        }\n\n        public async Task SendHeartBeat()\n        {\n            if (_healthConnection == null)\n            {\n                Trace.TraceError(\n                    FormatMessage(\"Health monitoring is not supported for this app. Check your AppConfig.json file\"));\n                return;\n            }\n            Trace.TraceInformation(FormatMessage(\"Sending heart beat message to Yams..\"));\n            await _healthConnection.SendMessage(\"[HEALTH_OK]\")\n                .Timeout(_config.HeartBeatMessageTimeout, FormatMessage(\"Send heart beat message to Yams has timed out\"));\n            Trace.TraceInformation(FormatMessage(\"Heart beat message has been sent to Yams successfully!\"));\n        }\n\n        public void Dispose()\n        {\n            _initConnection?.Dispose();\n            _exitConnection?.Dispose();\n            _healthConnection?.Dispose();\n        }\n\n        private async Task WaitForExit()\n        {\n            if(_exitConnection == null)\n            {\n                return;\n            }\n            while (true)\n            {\n                Trace.TraceInformation(FormatMessage(\"Waiting for an exit message from Yams..\"));\n                string msg = await _exitConnection.ReadMessage();\n                if (msg == \"[EXIT]\")\n                {\n                    Trace.TraceInformation(FormatMessage(\"Exit request received from Yams\"));\n                    ExitMessageReceived?.Invoke(this, EventArgs.Empty);\n                    break;\n                }\n                Trace.TraceError(FormatMessage($\"Unexpected message received from Yams: {msg}, Expected [EXIT]\"));\n            }\n        }\n\n        private string FormatMessage(string message)\n        {\n            return $\"[{_options.AppName} ({_options.AppVersion})] {message}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Client/YamsClientConfig.cs",
    "content": "using System;\n\nnamespace Etg.Yams.Client\n{\n    public class YamsClientConfig\n    {\n        public YamsClientConfig(TimeSpan connectTimeout, TimeSpan initDoneMessageTimeout,\n            TimeSpan heartBeatMessageTimeout, string[] processArgs)\n        {\n            ConnectTimeout = connectTimeout;\n            InitDoneMessageTimeout = initDoneMessageTimeout;\n            HeartBeatMessageTimeout = heartBeatMessageTimeout;\n            ProcessArgs = processArgs;\n        }\n\n        public TimeSpan ConnectTimeout { get; }\n        public TimeSpan InitDoneMessageTimeout { get; }\n        public TimeSpan HeartBeatMessageTimeout { get; }\n        public string[] ProcessArgs { get; set; }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Client/YamsClientConfigBuilder.cs",
    "content": "using System;\n\nnamespace Etg.Yams.Client\n{\n    public class YamsClientConfigBuilder\n    {\n        private readonly string[] _processArgs;\n        private TimeSpan _connectTimeout = TimeSpan.FromSeconds(30);\n        private TimeSpan _initDoneMessageTimeout = TimeSpan.FromSeconds(30);\n        private TimeSpan _heartBeatMessageTimeout = TimeSpan.FromSeconds(30);\n\n        public YamsClientConfigBuilder(string[] processArgs)\n        {\n            _processArgs = processArgs;\n        }\n\n        public YamsClientConfigBuilder SetConnectTimeout(TimeSpan timeout)\n        {\n            _connectTimeout = timeout;\n            return this;\n        }\n\n        public YamsClientConfigBuilder SetInitDoneMessageTimeout(TimeSpan timeout)\n        {\n            _initDoneMessageTimeout = timeout;\n            return this;\n        }\n\n        public YamsClientConfigBuilder SetHeartBeatMessageTimeout(TimeSpan timeout)\n        {\n            _heartBeatMessageTimeout = timeout;\n            return this;\n        }\n\n        public YamsClientConfig Build()\n        {\n            return new YamsClientConfig(_connectTimeout, _initDoneMessageTimeout,\n                _heartBeatMessageTimeout, _processArgs);\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Client/YamsClientFactory.cs",
    "content": "using System;\nusing CommandLine;\nusing Etg.Yams.Ipc;\n\nnamespace Etg.Yams.Client\n{\n    public class YamsClientFactory : IYamsClientFactory\n    {\n        private readonly IProcessArgsParser _processArgsParser;\n\n        public YamsClientFactory() : this(new ProcessArgsParser())\n        {\n        }\n\n        public YamsClientFactory(IProcessArgsParser processArgsParser)\n        {\n            _processArgsParser = processArgsParser;\n        }\n\n        public IYamsClient CreateYamsClient(YamsClientConfig config)\n        {\n            var options = _processArgsParser.ParseArgs(config.ProcessArgs);\n\n            IpcConnection initConnection = null;\n            IpcConnection exitConnection = null;\n            IpcConnection healthConnection = null;\n\n            if (!string.IsNullOrEmpty(options.InitializationPipeName))\n            {\n                initConnection = new IpcConnection(new NamedPipeClientAdapter(options.InitializationPipeName));\n            }\n            if (!string.IsNullOrEmpty(options.ExitPipeName))\n            {\n                exitConnection = new IpcConnection(new NamedPipeClientAdapter(options.ExitPipeName));\n            }\n            if (!string.IsNullOrEmpty(options.HealthPipeName))\n            {\n                healthConnection = new IpcConnection(new NamedPipeClientAdapter(options.HealthPipeName));\n            }\n            return new YamsClient(options, config, initConnection, exitConnection, healthConnection);\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Client/YamsClientOptions.cs",
    "content": "using CommandLine;\n\nnamespace Etg.Yams.Client\n{\n    public class YamsClientOptions\n    {\n        [Option()]\n        public string AppName { get; set; }\n        [Option()]\n        public string AppVersion { get; set; }\n        [Option()]\n        public string InitializationPipeName { get; set; }\n        [Option()]\n        public string ExitPipeName { get; set; }\n        [Option()]\n        public string HealthPipeName { get; set; }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Client/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "src/Etg.Yams.Core/Application/AppIdentity.cs",
    "content": "﻿using System;\nusing Semver;\nusing Newtonsoft.Json;\n\nnamespace Etg.Yams.Application\n{\n    public class AppIdentity : IEquatable<AppIdentity>\n    {\n        private readonly string _id;\n        private readonly SemVersion _version;\n\n        /// <summary>\n        /// A unique identifier for an application represented by an <see cref=\"Id\"/> and a <see cref=\"Version\"/>/>\n        /// </summary>\n        /// <param name=\"id\"></param>\n        /// <param name=\"version\"></param>\n        public AppIdentity(string id, SemVersion version)\n        {\n            _id = id;\n            _version = version;\n        }\n\n        [JsonConstructor]\n        public AppIdentity(string id, string version)\n        {\n            _id = id;\n            _version = SemVersion.Parse(version);\n        }\n\n        public override string ToString()\n        {\n            return string.Format(\"[{0} ({1})]\", Id, Version);\n        }\n\n        public string Id\n        {\n            get { return _id; }\n        }\n\n        public SemVersion Version\n        {\n            get { return _version; }\n        }\n\n        public bool Equals(AppIdentity other)\n        {\n            if (ReferenceEquals(null, other)) return false;\n            if (ReferenceEquals(this, other)) return true;\n            return string.Equals(_id, other._id) && Equals(_version, other._version);\n        }\n\n        public override bool Equals(object obj)\n        {\n            if (ReferenceEquals(null, obj)) return false;\n            if (ReferenceEquals(this, obj)) return true;\n            if (obj.GetType() != this.GetType()) return false;\n            return Equals((AppIdentity)obj);\n        }\n\n        public override int GetHashCode()\n        {\n            unchecked\n            {\n                return ((_id != null ? _id.GetHashCode() : 0) * 397) ^ (_version != null ? _version.GetHashCode() : 0);\n            }\n        }\n\n        public static bool operator ==(AppIdentity left, AppIdentity right)\n        {\n            return Equals(left, right);\n        }\n\n        public static bool operator !=(AppIdentity left, AppIdentity right)\n        {\n            return !Equals(left, right);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Application/Application.cs",
    "content": "using System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\nusing Etg.Yams.Process;\n\nnamespace Etg.Yams.Application\n{\n    public abstract class Application : IApplication\n    {\n        protected Application(AppIdentity identity, string path)\n        {\n            Identity = identity;\n            Path = path;\n        }\n\n        protected async Task<bool> StartProcess(IProcess process, string args)\n        {\n            try\n            {\n                await process.Start(args);\n                process.Exited += OnProcessExited;\n                return true;\n            }\n            catch (Exception e)\n            {\n                Trace.TraceError($\"Could not start the host process for application {Identity}, Inner Exception: {e}\");\n                return false;    \n            }\n        }\n\n        protected void OnProcessExited(object sender, ProcessExitedArgs e)\n        {\n            var handler = Exited;\n            if (handler != null)\n            {\n                Trace.TraceInformation(\"The process for application {0} has exited unexpectedly\", Identity);\n                handler(this, new ApplicationExitedArgs { Message = e.Message, AppIdentity = Identity});\n            }\n        }\n\n        public AppIdentity Identity { get; private set; }\n\n        public string Path { get; private set; }\n\n        public abstract Task<bool> Start();\n        public abstract Task Stop();\n\n        public event EventHandler<ApplicationExitedArgs> Exited;\n        public abstract void Dispose();\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Application/ApplicationConfig.cs",
    "content": "﻿namespace Etg.Yams.Application\n{\n    public class ApplicationConfig\n    {\n        public AppIdentity Identity { get; }\n        public string ExeName { get; }\n        public string ExeArgs { get; }\n        public bool MonitorInitialization { get; }\n        public bool MonitorHealth { get; }\n        public bool GracefulShutdown { get; }\n\n        public ApplicationConfig(\n            AppIdentity identity,\n            string exeName,\n            string exeArgs,\n            bool monitorInitialization = false,\n            bool monitorHealth = false,\n            bool gracefulShutdown = false)\n        {\n            Identity = identity;\n            ExeArgs = exeArgs;\n            MonitorInitialization = monitorInitialization;\n            MonitorHealth = monitorHealth;\n            GracefulShutdown = gracefulShutdown;\n            ExeName = exeName;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Application/ApplicationConfigParser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing System.Text.RegularExpressions;\nusing System.Threading.Tasks;\nusing Etg.Yams.Install;\nusing Etg.Yams.Json;\n\nnamespace Etg.Yams.Application\n{\n    public class ApplicationConfigParser : IApplicationConfigParser\n    {\n        private readonly IApplicationConfigSymbolResolver _symbolResolver;\n        private readonly IJsonSerializer _jsonSerializer;\n\n        // ReSharper disable once ClassNeverInstantiated.Local\n        private class ApplicationConfigData\n        {\n#pragma warning disable 649\n            public string ExeName;\n            public string ExeArgs;\n            public bool MonitorInitialization;\n            public bool MonitorHealth;\n            public bool GracefulShutdown;\n#pragma warning restore 649\n        }\n\n        public ApplicationConfigParser(IApplicationConfigSymbolResolver symbolResolver, IJsonSerializer jsonSerializer)\n        {\n            _symbolResolver = symbolResolver;\n            _jsonSerializer = jsonSerializer;\n        }\n\n        public async Task<ApplicationConfig> ParseFile(string path, AppInstallConfig appInstallConfig)\n        {\n            using (StreamReader r = new StreamReader(path))\n            {\n                return await Parse(await _jsonSerializer.DeserializeAsync<ApplicationConfigData>(\n                    await r.ReadToEndAsync()), appInstallConfig);\n            }\n        }\n\n        private async Task<ApplicationConfig> Parse(ApplicationConfigData appConfigData, AppInstallConfig appInstallConfig)\n        {\n            string args = await SubstituteSymbols(appConfigData.ExeArgs, appInstallConfig);\n            return new ApplicationConfig(appInstallConfig.AppIdentity, appConfigData.ExeName, args,\n                appConfigData.MonitorInitialization, appConfigData.MonitorHealth, appConfigData.GracefulShutdown);\n        }\n\n        private async Task<string> SubstituteSymbols(string str, AppInstallConfig appInstallConfig)\n        {\n            ISet<string> symbols = new HashSet<string>();\n            const string pattern = @\"\\{(.*?)\\}\";\n            foreach (Match m in Regex.Matches(str, pattern))\n            {\n                symbols.Add(m.Groups[1].ToString());\n            }\n\n            foreach (string symbol in symbols)\n            {\n                str = await SubstitueSymbol(str, symbol, appInstallConfig);\n            }\n            return str;\n        }\n\n        private async Task<string> SubstitueSymbol(string str, string symbol, AppInstallConfig appInstallConfig)\n        {\n            string symbolValue = await _symbolResolver.ResolveSymbol(appInstallConfig, symbol);\n            return str.Replace($\"${{{symbol}}}\", symbolValue);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Application/ApplicationConfigSymbolResolver.cs",
    "content": "using System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Etg.Yams.Install;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Application\n{\n    public class ApplicationConfigSymbolResolver : IApplicationConfigSymbolResolver\n    {\n        private readonly string _instanceId;\n        private readonly IReadOnlyDictionary<string, string> _clusterProperties;\n        private readonly string _clusterId;\n\n        public ApplicationConfigSymbolResolver(string clusterId, string instanceId) : this(clusterId, instanceId, new Dictionary<string, string>())\n        {\n        }\n\n        public ApplicationConfigSymbolResolver(string clusterId, string instanceId, IReadOnlyDictionary<string, string> clusterProperties)\n        {\n            _instanceId = instanceId;\n            _clusterProperties = clusterProperties;\n            _clusterId = clusterId;\n        }\n\n        public Task<string> ResolveSymbol(AppInstallConfig appInstallConfig, string symbol)\n        {\n            string symbolValue = symbol;\n            AppIdentity appIdentity = appInstallConfig.AppIdentity;\n            switch (symbol)\n            {\n                case \"Id\":\n                    symbolValue = appIdentity.Id;\n                    break;\n                case \"Version\":\n                    symbolValue = appIdentity.Version.ToString();\n                    break;\n                case \"Version.Major\":\n                    symbolValue = appIdentity.Version.Major.ToString();\n                    break;\n                case \"Version.Minor\":\n                    symbolValue = appIdentity.Version.Minor.ToString();\n                    break;\n                case \"Version.Build\":\n                    symbolValue = appIdentity.Version.Patch.ToString();\n                    break;\n                case \"Version.Prerelease\":\n                    symbolValue = appIdentity.Version.Prerelease;\n                    break;\n                case \"ClusterId\":\n                    symbolValue = _clusterId;\n                    break;\n                case \"InstanceId\":\n                    symbolValue = _instanceId;\n                    break;\n                default:\n                    if (!appInstallConfig.Properties.TryGetValue(symbol, out symbolValue))\n                    {\n                        _clusterProperties.TryGetValue(symbol, out symbolValue);\n                    }\n                    break;\n            }\n            return Task.FromResult(symbolValue);\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Application/ApplicationPool.cs",
    "content": "﻿using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Application\n{\n    public class ApplicationPool : IApplicationPool\n    {\n        private readonly ConcurrentDictionary<AppIdentity, IApplication> _applications;\n\n        public ApplicationPool()\n        {\n            _applications = new ConcurrentDictionary<AppIdentity, IApplication>();\n        }\n\n        public async Task AddApplication(IApplication application)\n        {\n            if (HasApplication(application.Identity))\n            {\n                throw new ArgumentException(\n                    $\"Cannot add application {application.Identity} to the application pool because it is already there\");\n            }\n\n            if (! await StartApplication(application))\n            {\n                throw new Exception($\"Failed to start application {application.Identity}\");\n            }\n\n            if (!_applications.TryAdd(application.Identity, application))\n            {\n                throw new Exception(\n                    $\"Could not add the application {application.Identity} to the concurent dictionary. This is likely a bug\");\n            }\n            application.Exited += OnApplicationExited;\n        }\n\n        public bool HasApplication(AppIdentity appIdentity)\n        {\n            return _applications.ContainsKey(appIdentity);\n        }\n\n        public IApplication GetApplication(AppIdentity appIdentity)\n        {\n            if (!HasApplication(appIdentity))\n            {\n                return null;\n            }\n            return _applications[appIdentity];\n        }\n\n        public IEnumerable<IApplication> Applications => _applications.Values;\n\n        public async Task RemoveApplication(AppIdentity appIdentity)\n        {\n            IApplication application;\n            if (!_applications.TryRemove(appIdentity, out application))\n            {\n                throw new ArgumentException(\n                    $\"Cannot remove application {appIdentity} because it doesn't exist in the pool\");\n            }\n            application.Exited -= OnApplicationExited;\n            try\n            {\n                await application.Stop();\n                application.Dispose();\n                await Task.Delay(5000);\n            }\n            catch (Exception e)\n            {\n                Trace.TraceError($\"Exception occured while stopping Application {appIdentity}, Exception: {e}\");\n            }\n        }\n\n        private static async Task<bool> StartApplication(IApplication application)\n        {\n            if (!await application.Start())\n            {\n                Trace.TraceError(\"Could not start application {0}\", application.Identity);\n                return false;\n            }\n            Trace.TraceInformation(\"Successfully started application {0}\", application.Identity);\n            return true;\n        }\n\n        private void OnApplicationExited(object sender, ApplicationExitedArgs args)\n        {\n            AppIdentity appIdentity = args.AppIdentity;\n            Trace.TraceError($\"Application {appIdentity} exited unexpectedly with message {args.Message}\");\n            if (_applications.ContainsKey(appIdentity))\n            {\n                RemoveApplication(appIdentity).GetAwaiter().GetResult();\n            }\n        }\n\n        public async Task Shutdown()\n        {\n            foreach (var application in _applications.Values)\n            {\n                await application.Stop();\n            }\n            _applications.Clear();\n        }\n\n        public void Dispose()\n        {\n            var tasks = new List<Task>();\n            foreach (IApplication application in Applications)\n            {\n                tasks.Add(RemoveApplication(application.Identity));\n                application.Dispose();\n            }\n            Task.WhenAll(tasks).Wait();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Application/ConfigurableApplication.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Process;\n\nnamespace Etg.Yams.Application\n{\n    public class ConfigurableApplication : Application\n    {\n        private readonly ApplicationConfig _appConfig;\n        private readonly IProcessFactory _processFactory;\n        private readonly IProcessStopper _processStopper;\n        private IProcess _process;\n\n        /// <summary>\n        /// A configurable application is a generic application that can be started using a given exe and exe args.\n        /// </summary>\n        /// <param name=\"path\">The path of the directory where the exe is located</param>\n        /// <param name=\"appConfig\">exe name, args, etc.</param>\n        /// <param name=\"processFactory\">A factory to create a process to run the exe</param>\n        /// <param name=\"processStopper\">Used to stop a process</param>\n        public ConfigurableApplication(string path, ApplicationConfig appConfig, IProcessFactory processFactory,\n            IProcessStopper processStopper) : base(appConfig.Identity, path)\n        {\n            _appConfig = appConfig;\n            _processFactory = processFactory;\n            _processStopper = processStopper;\n        }\n\n        public override Task<bool> Start()\n        {\n            _process = _processFactory.CreateProcess(_appConfig.Identity, System.IO.Path.Combine(Path, _appConfig.ExeName),\n            _appConfig.MonitorInitialization, _appConfig.MonitorHealth, _appConfig.GracefulShutdown);\n            return StartProcess(_process, _appConfig.ExeArgs);\n        }\n\n        public override Task Stop()\n        {\n            return _processStopper.StopProcess(_process);\n        }\n\n        public override void Dispose()\n        {\n            _process.Dispose();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Application/ConfigurableApplicationFactory.cs",
    "content": "﻿using System.IO;\nusing System.Threading.Tasks;\nusing Etg.Yams.Install;\nusing Etg.Yams.Process;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Application\n{\n    public class ConfigurableApplicationFactory : IApplicationFactory\n    {\n        private readonly IApplicationConfigParser _appConfigParser;\n        private readonly IProcessFactory _processFactory;\n        private readonly IProcessStopper _processStopper;\n\n        public ConfigurableApplicationFactory(IApplicationConfigParser appConfigParser, IProcessFactory processFactory, IProcessStopper processStopper)\n        {\n            _appConfigParser = appConfigParser;\n            _processFactory = processFactory;\n            _processStopper = processStopper;\n        }\n\n        public async Task<IApplication> CreateApplication(AppInstallConfig appInstallConfig, string appPath)\n        {\n            string appConfigPath = Path.Combine(appPath, Constants.AppConfigFileName);\n            ApplicationConfig appConfig = await _appConfigParser.ParseFile(appConfigPath, appInstallConfig);\n            return new ConfigurableApplication(appPath, appConfig, _processFactory, _processStopper);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Application/IApplication.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Application\n{\n    /// <summary>\n    /// Represents an application that will be deployed and hosted in YAMS. An application is uniquely identified by\n    /// an id and a version.\n    /// </summary>\n    public interface IApplication : IDisposable\n    {\n        AppIdentity Identity { get; }\n\n        /// <summary>\n        /// The path where the application has been installed.\n        /// </summary>\n        string Path { get; }\n\n        Task<bool> Start();\n\n        Task Stop();\n\n        /// <summary>\n        /// Is triggered if the application exited before <see cref=\"Stop\"/> is called. The event will not be emitted \n        /// when <see cref=\"Stop\"/> is called.\n        /// </summary>\n        event EventHandler<ApplicationExitedArgs> Exited;\n    }\n\n    public class ApplicationExitedArgs : EventArgs\n    {\n        public AppIdentity AppIdentity { get; set; }\n\n        public string Message { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Application/IApplicationConfigParser.cs",
    "content": "using System.Threading.Tasks;\nusing Etg.Yams.Install;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Application\n{\n    public interface IApplicationConfigParser\n    {\n        /// <summary>\n        /// Parses the application config file.\n        /// </summary>\n        /// <param name=\"path\">The absolute path of the application config file</param>\n        /// <param name=\"appInstallConfig\">The installation config of the corresponding app</param>\n        /// <returns></returns>\n        Task<ApplicationConfig> ParseFile(string path, AppInstallConfig appInstallConfig);\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Application/IApplicationConfigSymbolResolver.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Install;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Application\n{\n    public interface IApplicationConfigSymbolResolver\n    {\n        /// <summary>\n        /// Resolves the given symbol for the given app.\n        /// Symbols are used in the AppConfig.json file with the syntax ${symbol}.\n        /// </summary>\n        /// <param name=\"appDeploymentConfig\">The deployment configuration of the app involved</param>\n        /// <param name=\"symbol\">The symbol to resolve WITHOUT the $ and brackets</param>\n        /// <returns>The value of the symbol</returns>\n        Task<string> ResolveSymbol(AppInstallConfig appInstallConfig, string symbol);\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Application/IApplicationFactory.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Install;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Application\n{\n    public interface IApplicationFactory\n    {\n        Task<IApplication> CreateApplication(AppInstallConfig appInstallConfig, string appPath);\n    }\n    }\n"
  },
  {
    "path": "src/Etg.Yams.Core/Application/IApplicationPool.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Application\n{\n    public interface IApplicationPool : IDisposable\n    {\n        /// <summary>\n        /// Will start the given application and add it to the pool.\n        /// </summary>\n        /// <param name=\"application\"></param>\n        /// <returns></returns>\n        Task AddApplication(IApplication application);\n\n        /// <summary>\n        /// Will stop the application and remove it from the pool.\n        /// </summary>\n        /// <param name=\"appIdentity\"></param>\n        /// <returns></returns>\n        Task RemoveApplication(AppIdentity appIdentity);\n\n        bool HasApplication(AppIdentity appIdentity);\n\n        /// <summary>\n        /// Returns null if the application is not in the pool.\n        /// </summary>\n        /// <param name=\"appIdentity\"></param>\n        /// <returns></returns>\n        IApplication GetApplication(AppIdentity appIdentity);\n\n        /// <summary>\n        /// All running applications.\n        /// </summary>\n        IEnumerable<IApplication> Applications { get; }\n\n        /// <summary>\n        /// Stops all applications and removes them from the pool.\n        /// </summary>\n        /// <returns></returns>\n        Task Shutdown();\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Constants.cs",
    "content": "﻿namespace Etg.Yams\n{\n    public static class Constants\n    {\n        public const string AppConfigFileName = \"AppConfig.json\";\n        public const string DeploymentConfigFileName = \"DeploymentConfig.json\";\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Deploy/AndDeploymentMatcher.cs",
    "content": "using System.Linq;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Deploy\n{\n    public class AndDeploymentMatcher : IAppDeploymentMatcher\n    {\n        private readonly IAppDeploymentMatcher[] _matchers;\n\n        public AndDeploymentMatcher(params IAppDeploymentMatcher[] matchers)\n        {\n            _matchers = matchers;\n        }\n\n        public bool IsMatch(AppDeploymentConfig appDeploymentConfig)\n        {\n            return _matchers.All(matcher => matcher.IsMatch(appDeploymentConfig));\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Deploy/ClusterIdDeploymentMatcher.cs",
    "content": "﻿using System.Linq;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Deploy\n{\n    public class ClusterIdDeploymentMatcher : IAppDeploymentMatcher\n    {\n        private readonly string _clusterId;\n\n        public ClusterIdDeploymentMatcher(string clusterId)\n        {\n            _clusterId = clusterId;\n        }\n\n        public bool IsMatch(AppDeploymentConfig appDeploymentConfig)\n        {\n            return appDeploymentConfig.TargetClusters.Contains(_clusterId);\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Deploy/IAppDeploymentMatcher.cs",
    "content": "﻿using Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Deploy\n{\n    public interface IAppDeploymentMatcher\n    {\n        /// <summary>\n        /// This interface is used to determine if an app should be deployed to the current cluster or not.\n        /// </summary>\n        /// <param name=\"appDeploymentConfig\"></param>\n        /// <returns>True if the app corresponding to the given AppDeploymentConfig should be deployed to the current cluster, \n        /// false otherwise</returns>\n        bool IsMatch(AppDeploymentConfig appDeploymentConfig);\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Deploy/IApplicationDeploymentDirectory.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Deploy\n{\n    public interface IApplicationDeploymentDirectory\n    {\n        /// <returns>the list of application that should be deployed to the current cluster</returns>\n        Task<IEnumerable<AppDeploymentConfig>> FetchDeployments();\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Deploy/PropertiesDeploymentMatcher.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Deploy\n{\n    public class PropertiesDeploymentMatcher : IAppDeploymentMatcher\n    {\n        private readonly IReadOnlyDictionary<string, string> _matchProperties; \n        public PropertiesDeploymentMatcher(IReadOnlyDictionary<string, string> matchProperties)\n        {\n            _matchProperties = matchProperties.ToDictionary(pair => pair.Key, pair => pair.Value);\n        }\n\n        public bool IsMatch(AppDeploymentConfig appDeploymentConfig)\n        {\n            foreach (var kvp in _matchProperties)\n            {\n                string value;\n                if (appDeploymentConfig.Properties.TryGetValue(kvp.Key, out value))\n                {\n                    if (value != kvp.Value)\n                    {\n                        return false;\n                    }\n                }\n            }\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Deploy/RemoteApplicationDeploymentDirectory.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Deploy\n{\n    /// <summary>\n    /// A proxy object to the blob storage where applications resources are located. This class can read the configuration file\n    /// located in the blob storage to figure out what should be deployed where.\n    /// </summary>\n    public class RemoteApplicationDeploymentDirectory : IApplicationDeploymentDirectory\n    {\n        private readonly IDeploymentRepository _deploymentRepository;\n        private readonly IAppDeploymentMatcher _appDeploymentMatcher;\n\n        public RemoteApplicationDeploymentDirectory(IDeploymentRepository deploymentRepository, IAppDeploymentMatcher appDeploymentMatcher)\n        {\n            _deploymentRepository = deploymentRepository;\n            _appDeploymentMatcher = appDeploymentMatcher;\n        }\n\n        public async Task<IEnumerable<AppDeploymentConfig>> FetchDeployments()\n        {\n            var apps = new HashSet<AppDeploymentConfig>();\n\n            DeploymentConfig deploymentConfig = await _deploymentRepository.FetchDeploymentConfig();\n\n            foreach (AppDeploymentConfig appDeploymentConfig in deploymentConfig.Where(_appDeploymentMatcher.IsMatch))\n            {\n                AppIdentity appIdentity = appDeploymentConfig.AppIdentity;\n                try\n                {\n                    if (!await _deploymentRepository.HasApplicationBinaries(appIdentity))\n                    {\n                        Trace.TraceError($\"Could not find binaries for application {appIdentity} in the yams repository\");\n                        continue;\n                    }\n\n                    apps.Add(appDeploymentConfig);\n                }\n                catch (Exception e)\n                {\n                    Trace.TraceError($\"Exception occured while loading application {appIdentity}, Exception: {e}\");\n                }\n            }\n            return apps;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Download/ApplicationDownloader.cs",
    "content": "using System.Diagnostics;\nusing System.IO;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Utils;\n\nnamespace Etg.Yams.Download\n{\n    public class ApplicationDownloader : IApplicationDownloader\n    {\n        private readonly string _applicationRootPath;\n        private readonly IDeploymentRepository _deploymentRepository;\n\n        /// <summary>\n        /// Downloads application from the remote directory to the local file system.\n        /// </summary>\n        /// <param name=\"applicationRootPath\">The target path where the applications will be downloaded</param>\n        /// <param name=\"deploymentRepository\"></param>\n        public ApplicationDownloader(string applicationRootPath, IDeploymentRepository deploymentRepository)\n        {\n            _applicationRootPath = applicationRootPath;\n            _deploymentRepository = deploymentRepository;\n        }\n\n        public async Task DownloadApplication(AppIdentity appIdentity)\n        {\n            Trace.TraceInformation($\"Downloading application {appIdentity}\");\n            try\n            {\n                string destPath = Path.Combine(_applicationRootPath,\n                    ApplicationUtils.GetApplicationRelativePath(appIdentity));\n                await\n                    _deploymentRepository.DownloadApplicationBinaries(appIdentity, destPath,\n                        ConflictResolutionMode.OverwriteExistingBinaries);\n                Trace.TraceInformation($\"Application {appIdentity} downloaded\");\n            }\n            catch (BinariesNotFoundException)\n            {\n                Trace.TraceError(\n                    $\"{appIdentity} could not be downloaded because it was not found in the Yams repository\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Download/IApplicationDownloader.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Application;\n\nnamespace Etg.Yams.Download\n{\n    public interface IApplicationDownloader\n    {\n        /// <summary>\n        /// Download the application associated with the given <see cref=\"AppIdentity\"/> to the current Role instance.\n        /// </summary>\n        /// <param name=\"appIdentity\"></param>\n        /// <returns></returns>\n        Task DownloadApplication(AppIdentity appIdentity);\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Etg.Yams.Core.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{7145E485-34FA-4632-89B0-BD27C96AF69C}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams</RootNamespace>\n    <AssemblyName>Etg.Yams.Core</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\netstandard1.1\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.ComponentModel.Composition\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Application\\AppIdentity.cs\" />\n    <Compile Include=\"Application\\Application.cs\" />\n    <Compile Include=\"Application\\ApplicationConfig.cs\" />\n    <Compile Include=\"Application\\ApplicationConfigParser.cs\" />\n    <Compile Include=\"Application\\ApplicationConfigSymbolResolver.cs\" />\n    <Compile Include=\"Application\\ApplicationPool.cs\" />\n    <Compile Include=\"Application\\ConfigurableApplication.cs\" />\n    <Compile Include=\"Application\\ConfigurableApplicationFactory.cs\" />\n    <Compile Include=\"Application\\IApplication.cs\" />\n    <Compile Include=\"Application\\IApplicationConfigParser.cs\" />\n    <Compile Include=\"Application\\IApplicationConfigSymbolResolver.cs\" />\n    <Compile Include=\"Application\\IApplicationFactory.cs\" />\n    <Compile Include=\"Application\\IApplicationPool.cs\" />\n    <Compile Include=\"Constants.cs\" />\n    <Compile Include=\"Deploy\\AndDeploymentMatcher.cs\" />\n    <Compile Include=\"Deploy\\ClusterIdDeploymentMatcher.cs\" />\n    <Compile Include=\"Deploy\\IAppDeploymentMatcher.cs\" />\n    <Compile Include=\"Deploy\\IApplicationDeploymentDirectory.cs\" />\n    <Compile Include=\"Deploy\\PropertiesDeploymentMatcher.cs\" />\n    <Compile Include=\"Deploy\\RemoteApplicationDeploymentDirectory.cs\" />\n    <Compile Include=\"IYamsService.cs\" />\n    <Compile Include=\"Os\\ISystem.cs\" />\n    <Compile Include=\"Os\\System.cs\" />\n    <Compile Include=\"Os\\SystemExtensions.cs\" />\n    <Compile Include=\"Process\\AbstractProcessDecorator.cs\" />\n    <Compile Include=\"Process\\GracefullShutdownProcessDecorator.cs\" />\n    <Compile Include=\"Process\\MonitorInitProcessDecorator.cs\" />\n    <Compile Include=\"Process\\HealthProcessDecorator.cs\" />\n    <Compile Include=\"Storage\\Config\\AppDeploymentConfig.cs\" />\n    <Compile Include=\"Install\\AppInstallConfig.cs\" />\n    <Compile Include=\"Storage\\Config\\IDeploymentConfigSerializer.cs\" />\n    <Compile Include=\"Storage\\Config\\JsonDeploymentConfigSerializer.cs\" />\n    <Compile Include=\"Storage\\IDeploymentStatusReader.cs\" />\n    <Compile Include=\"Storage\\IDeploymentStatusWriter.cs\" />\n    <Compile Include=\"Storage\\Status\\AppDeploymentStatus.cs\" />\n    <Compile Include=\"Storage\\Status\\ClusterDeploymentStatus.cs\" />\n    <Compile Include=\"Storage\\Status\\DeploymentStatus.cs\" />\n    <Compile Include=\"Storage\\Status\\IDeploymentStatusSerializer.cs\" />\n    <Compile Include=\"Storage\\Status\\InstanceDeploymentStatus.cs\" />\n    <Compile Include=\"Storage\\Status\\JsonDeploymentStatusSerializer.cs\" />\n    <Compile Include=\"Utils\\EnvironmentUtils.cs\" />\n    <Compile Include=\"YamsDiModule.cs\" />\n    <Compile Include=\"Download\\ApplicationDownloader.cs\" />\n    <Compile Include=\"Download\\IApplicationDownloader.cs\" />\n    <Compile Include=\"Install\\ApplicationInstaller.cs\" />\n    <Compile Include=\"Install\\IApplicationInstaller.cs\" />\n    <Compile Include=\"Process\\IProcess.cs\" />\n    <Compile Include=\"Process\\IProcessFactory.cs\" />\n    <Compile Include=\"Process\\IProcessStopper.cs\" />\n    <Compile Include=\"Process\\Process.cs\" />\n    <Compile Include=\"Process\\ProcessStopper.cs\" />\n    <Compile Include=\"Process\\SelfRestartingProcess.cs\" />\n    <Compile Include=\"Process\\ProcessFactory.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Storage\\BinariesNotFoundException.cs\" />\n    <Compile Include=\"Storage\\Config\\DeploymentConfig.cs\" />\n    <Compile Include=\"Storage\\ConflictResolutionMode.cs\" />\n    <Compile Include=\"Storage\\DuplicateBinariesException.cs\" />\n    <Compile Include=\"Storage\\IDeploymentRepository.cs\" />\n    <Compile Include=\"Update\\ApplicationUpdateManager.cs\" />\n    <Compile Include=\"Update\\IApplicationUpdateManager.cs\" />\n    <Compile Include=\"Update\\IUpdateSessionManager.cs\" />\n    <Compile Include=\"Utils\\ApplicationUtils.cs\" />\n    <Compile Include=\"Utils\\ProcessUtils.cs\" />\n    <Compile Include=\"Watcher\\DeploymentWatcher.cs\" />\n    <Compile Include=\"Watcher\\IDeploymentWatcher.cs\" />\n    <Compile Include=\"YamsConfig.cs\" />\n    <Compile Include=\"YamsConfigBuilder.cs\" />\n    <Compile Include=\"YamsService.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\">\n      <SubType>Designer</SubType>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Common\\Common.csproj\">\n      <Project>{3e982150-5b43-44da-8d96-66cf07a9a14c}</Project>\n      <Name>Common</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Etg.Yams.Ipc\\Etg.Yams.Ipc.csproj\">\n      <Project>{c7c03d37-f2d2-4115-8423-86c1bf1b8a18}</Project>\n      <Name>Etg.Yams.Ipc</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup />\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "src/Etg.Yams.Core/IYamsService.cs",
    "content": "﻿using System.Threading.Tasks;\n\nnamespace Etg.Yams\n{\n    public interface IYamsService\n    {\n        Task Start();\n        Task Stop();\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Install/AppInstallConfig.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing Etg.Yams.Application;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Utils;\n\nnamespace Etg.Yams.Install\n{\n    public class AppInstallConfig\n    {\n        public AppInstallConfig(AppIdentity appIdentity, IReadOnlyDictionary<string, string> properties) : this(appIdentity)\n        {\n            Properties = properties.ToDictionary(pair => pair.Key, pair => pair.Value);\n        }\n\n        public AppInstallConfig(AppIdentity appIdentity)\n        {\n            AppIdentity = appIdentity;\n            Properties = new Dictionary<string, string>();\n        }\n\n        protected bool Equals(AppDeploymentConfig other)\n        {\n            bool res = Equals(AppIdentity, other.AppIdentity)\n                       && Properties.SequenceEqual(other.Properties);\n            return res;\n        }\n\n        public override bool Equals(object obj)\n        {\n            if (ReferenceEquals(null, obj)) return false;\n            if (ReferenceEquals(this, obj)) return true;\n            if (obj.GetType() != this.GetType()) return false;\n            return Equals((AppDeploymentConfig)obj);\n        }\n\n        public override int GetHashCode()\n        {\n            unchecked\n            {\n                var hashCode = (AppIdentity != null ? AppIdentity.GetHashCode() : 0);\n                hashCode = (hashCode * 397) ^ (Properties != null ? HashCodeUtils.GetHashCode(Properties) : 0);\n                return hashCode;\n            }\n        }\n\n        public AppIdentity AppIdentity { get; }\n\n        public IReadOnlyDictionary<string, string> Properties { get; }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Install/ApplicationInstaller.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Update;\nusing Etg.Yams.Utils;\n\nnamespace Etg.Yams.Install\n{\n    public class ApplicationInstaller : IApplicationInstaller\n    {\n        private readonly string _applicationsRootPath;\n        private readonly IApplicationFactory _applicationFactory;\n        private readonly IApplicationPool _applicationPool;\n\n        public ApplicationInstaller(string applicationsRootPath, \n            IApplicationFactory applicationFactory, IApplicationPool applicationPool)\n        {\n            _applicationsRootPath = applicationsRootPath;\n            _applicationFactory = applicationFactory;\n            _applicationPool = applicationPool;\n        }\n\n        public async Task Install(AppInstallConfig appInstallConfig)\n        {\n            AppIdentity appIdentity = appInstallConfig.AppIdentity;\n            Trace.TraceInformation($\"Installing application {appIdentity}\");\n            IApplication application =\n                await _applicationFactory.CreateApplication(appInstallConfig, \n                GetApplicationAbsolutePath(appInstallConfig.AppIdentity));\n            try\n            {\n                await _applicationPool.AddApplication(application);\n                Trace.TraceInformation($\"Application {appIdentity} installed\");\n            }\n            catch (Exception e)\n            {\n                await DeleteAppBinaries(appInstallConfig.AppIdentity);\n                throw new Exception($\"Failed to install application {appIdentity}\", e);\n            }\n        }\n\n        public async Task UnInstall(AppIdentity appIdentity)\n        {\n            try\n            {\n                Trace.TraceInformation($\"Uninstalling application {appIdentity}\");\n                await _applicationPool.RemoveApplication(appIdentity);\n                await DeleteAppBinaries(appIdentity);\n                Trace.TraceInformation($\"Application {appIdentity} uninstalled\");\n            }\n            catch (Exception e)\n            {\n                throw new Exception($\"Failed to uninstall application {appIdentity}\", e);\n            }\n        }\n\n        public async Task<bool> Update(IEnumerable<AppIdentity> applicationsToRemove, IEnumerable<AppInstallConfig> applicationsToDeploy)\n        {\n            if (!applicationsToDeploy.Any() || !applicationsToRemove.Any())\n            {\n                throw new ArgumentException(\"An update must at least involve an application to remove and an application to deploy\");\n            }\n\n            string appId = applicationsToDeploy.First().AppIdentity.Id;\n\n            bool failed = false;\n            try\n            {\n                await UnInstallApplications(applicationsToRemove);\n                await InstallApplications(applicationsToDeploy);\n            }\n            catch (AggregateException e)\n            {\n                failed = true;\n                TraceUtils.TraceAllErrors(\"Failed to update applications\", e);\n            }\n            catch (Exception e)\n            {\n                failed = true;\n                Trace.TraceError(\"Failed to update applications\", e);\n            }\n\n            return !failed;\n        }\n\n        private async Task DeleteAppBinaries(AppIdentity appIdentity)\n        {\n            await FileUtils.DeleteDirectoryIfAny(GetApplicationAbsolutePath(appIdentity), recursive: true);\n        }\n\n        private async Task UnInstallApplications(IEnumerable<AppIdentity> applicationsToRemove)\n        {\n            var tasks = new List<Task>();\n            foreach (AppIdentity appIdentity in applicationsToRemove)\n            {\n                tasks.Add(UnInstall(appIdentity));\n            }\n            await Task.WhenAll(tasks);\n        }\n\n        private async Task InstallApplications(IEnumerable<AppInstallConfig> applications)\n        {\n            var tasks = new List<Task>();\n            foreach (AppInstallConfig appInstallConfig in applications)\n            {\n                tasks.Add(Install(appInstallConfig));\n            }\n            await Task.WhenAll(tasks);\n        }\n\n        private string GetApplicationAbsolutePath(AppIdentity appIdentity)\n        {\n            return Path.Combine(_applicationsRootPath, ApplicationUtils.GetApplicationRelativePath(appIdentity));\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Install/IApplicationInstaller.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\n\nnamespace Etg.Yams.Install\n{\n    /// <summary>\n    /// An application installer is used to create, run and register an application.\n    /// The application must be downloaded before installation (downloading is NOT the responsibility of this class).\n    /// </summary>\n    public interface IApplicationInstaller\n    {\n        /// <summary>\n        /// Creates, runs and registers the application\n        /// </summary>\n        /// <param name=\"appInstallConfig\"></param>\n        /// <returns></returns>\n        Task Install(AppInstallConfig appInstallConfig);\n\n        /// <summary>\n        /// Stops and unregister the application.\n        /// </summary>\n        /// <param name=\"appIdentity\"></param>\n        /// <returns></returns>\n        Task UnInstall(AppIdentity appIdentity);\n\n        /// <summary>\n        /// Performs an update. All given applications must have the same application id.\n        /// The main difference between install/uninstall and update is that update obey the update domain.\n        /// In other words, applications are updated in one update domain at a time.\n        /// </summary>\n        /// <param name=\"applicationsToRemove\"></param>\n        /// <param name=\"applicationsToDeploy\"></param>\n        /// <returns></returns>\n        Task<bool> Update(IEnumerable<AppIdentity> applicationsToRemove, IEnumerable<AppInstallConfig> applicationsToDeploy);\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Os/ISystem.cs",
    "content": "﻿using System;\n\nnamespace Etg.Yams.Os\n{\n    /// <summary>\n    /// Interface to interact with the operating system. Add apis as needed.\n    /// </summary>\n    public interface ISystem\n    {\n        string GetEnvironmentVariable(string name, EnvironmentVariableTarget target);\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Os/System.cs",
    "content": "﻿using System;\n\nnamespace Etg.Yams.Os\n{\n    public class System : ISystem\n    {\n        public string GetEnvironmentVariable(string name, EnvironmentVariableTarget target)\n        {\n            return Environment.ExpandEnvironmentVariables(Environment.GetEnvironmentVariable(name, target));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Os/SystemExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Etg.Yams.Os\n{\n    public static class SystemExtensions\n    {\n        public static string GetPathEnvironmentVariable(this ISystem system)\n        {\n            var processPath = system.GetEnvironmentVariable(\"PATH\", EnvironmentVariableTarget.Process);\n            var machinePath = system.GetEnvironmentVariable(\"PATH\", EnvironmentVariableTarget.Machine);\n\n            // If initialization installed something (such as nodejs) that modifies the machine path, the path wouldn't be found \n            // on the first run after imaging. Therefore we merge the current machine path into the process path. This only works \n            // with UseShellExecute = false, UseShellExecute = true won't pass the process environment and creates a new one.\n            return MergePath(processPath, machinePath);\n        }\n\n        private static IEnumerable<string> SplitPath(string path)\n        {\n            return (path ?? string.Empty).Split(';').Where(entry => !string.IsNullOrWhiteSpace(entry));\n        }\n\n        private static string MergePath(string processPath, string machinePath)\n        {\n            var splitProcessPath = SplitPath(processPath);\n            var splitMachinePath = SplitPath(machinePath);\n            var mergedPath = splitProcessPath.Union(splitMachinePath);\n            return string.Join(\";\", mergedPath) + \";\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Process/AbstractProcessDecorator.cs",
    "content": "﻿using Etg.Yams.Application;\nusing System;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Process\n{\n    public class AbstractProcessDecorator : IProcess\n    {\n        protected readonly IProcess _process;\n\n        public event EventHandler<ProcessExitedArgs> Exited;\n\n        public AbstractProcessDecorator(AppIdentity identity, IProcess process)\n        {\n            Identity = identity;\n            _process = process;\n            _process.Exited += InvokeExited;\n        }\n\n        public AppIdentity Identity { get; }\n        public string ExePath => _process.ExePath;\n        public bool HasExited => _process.HasExited;\n        public bool IsRunning => _process.IsRunning;\n\n        public virtual void Dispose()\n        {\n            _process.Dispose();\n        }\n\n        public virtual Task Start(string args)\n        {\n            return _process.Start(args);\n        }\n\n        public virtual Task Close()\n        {\n            UnsubscribeFromExited();\n            return _process.Close();\n        }\n\n        public virtual Task Kill()\n        {\n            UnsubscribeFromExited();\n            return _process.Kill();\n        }\n\n        public virtual Task ReleaseResources()\n        {\n            UnsubscribeFromExited();\n            return _process.ReleaseResources();\n        }\n\n        protected void InvokeExited(object sender, ProcessExitedArgs args)\n        {\n            Exited?.Invoke(sender, args);\n        }\n\n        protected void UnsubscribeFromExited()\n        {\n            _process.Exited -= InvokeExited;\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Process/GracefullShutdownProcessDecorator.cs",
    "content": "using System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\nusing Etg.Yams.Utils;\nusing Etg.Yams.Ipc;\nusing Etg.Yams.Application;\n\nnamespace Etg.Yams.Process\n{\n    public class GracefulShutdownProcessDecorator : AbstractProcessDecorator\n    {\n        private readonly YamsConfig _config;\n        private readonly IIpcConnection _ipcConnection;\n\n        public GracefulShutdownProcessDecorator(AppIdentity identity, YamsConfig config, IProcess process, IIpcConnection ipcConnection)\n            : base(identity, process)\n        {\n            _config = config;\n            _ipcConnection = ipcConnection;\n        }\n\n        public override void Dispose()\n        {\n            base.Dispose();\n            _ipcConnection?.Dispose();\n        }\n\n        public override async Task Start(string args)\n        {\n            var startProcessTask =\n                _process.Start($\"{args} --ExitPipeName {_ipcConnection.ConnectionId}\");\n            await Task.WhenAll(startProcessTask, _ipcConnection.Connect().Timeout(_config.IpcConnectTimeout,\n                $\"Connecting to graceful exit pipe has timed out, make sure that the app {this.Identity} is connecting to the same pipe\"));\n        }\n\n        public override async Task Close()\n        {\n            Trace.TraceInformation($\"Yams is sending an exit message to the app {this.Identity}\");\n            try\n            {\n                UnsubscribeFromExited();\n\n                await _ipcConnection.SendMessage(\"[EXIT]\").Timeout(_config.GracefulShutdownMessageTimeout);\n\n                Trace.TraceInformation($\"Exit message sent to {this.Identity} !\");\n\n                await _ipcConnection.Disconnect();\n\n                if (!await ProcessUtils.SpinWaitForExit(this, (int) _config.AppGracefulShutdownTimeout.TotalSeconds))\n                {\n                    throw new TimeoutException($\"The app {this.Identity} did not exit in time\");\n                }\n                Trace.TraceInformation($\"App {this.Identity} has exited gracefully!\");\n            }\n            catch (TimeoutException e)\n            {\n                Trace.TraceError($\"App {this.Identity} did not respond to exit message, attempting to close the process.. {e.Message}\");\n                await _process.Close();\n                Trace.TraceInformation($\"App {this.Identity} has been closed\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Process/HealthProcessDecorator.cs",
    "content": "﻿using System.Diagnostics;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Ipc;\nusing Etg.Yams.Utils;\n\nnamespace Etg.Yams.Process\n{\n    public class HealthProcessDecorator : AbstractProcessDecorator\n    {\n        private readonly YamsConfig _config;\n        private readonly IIpcConnection _ipcConnection;\n        private CancellationTokenSource _watchProcessHealthCancellationTokenSource;\n        private Task _watchProcessHealthTask;\n\n        public HealthProcessDecorator(AppIdentity identity, YamsConfig config, IProcess process,\n            IIpcConnection ipcConnection) : base(identity, process)\n        {\n            _config = config;\n            _ipcConnection = ipcConnection;\n        }\n\n        public override async Task Start(string args)\n        {\n            await _process.Start($\"{args} --HealthPipeName {_ipcConnection.ConnectionId}\");\n\n            await _ipcConnection.Connect().Timeout(_config.IpcConnectTimeout,\n                $\"Connecting to health pipe has timed out, make sure that the app {this.Identity} is connecting to the same pipe\");\n\n            MonitorProcessHealth();\n        }\n\n        public override async Task Close()\n        {\n            await base.Close();\n            await StopMonitoringProcessHealth();\n        }\n\n        public override async Task Kill()\n        {\n            await base.Kill();\n            await StopMonitoringProcessHealth();\n        }\n\n        private void MonitorProcessHealth()\n        {\n            _watchProcessHealthCancellationTokenSource = new CancellationTokenSource();\n            CancellationToken cancellationToken = _watchProcessHealthCancellationTokenSource.Token;\n            _watchProcessHealthTask = Task.Run(async () =>\n            {\n                while (!cancellationToken.IsCancellationRequested)\n                {\n                    Trace.TraceInformation($\"Waiting for heart beat from app {this.Identity}\");\n                    Task<string> readMessageTask = _ipcConnection.ReadMessage();\n\n                    await WaitForHeartBeat(cancellationToken, readMessageTask);\n                }\n            }, cancellationToken);\n        }\n\n        private async Task WaitForHeartBeat(CancellationToken cancellationToken, Task<string> readMessageTask)\n        {\n            while (!cancellationToken.IsCancellationRequested)\n            {\n                var completedTask = await Task.WhenAny(readMessageTask,\n                    Task.Delay(_config.AppHeartBeatTimeout, cancellationToken));\n\n                if (completedTask == readMessageTask)\n                {\n                    string msg = readMessageTask.Result;\n                    if (msg == \"[HEALTH_OK]\")\n                    {\n                        Trace.TraceInformation($\"Heart beat received from App {this.Identity}; App is healthy\");\n                        break;\n                    }\n                    if (string.IsNullOrWhiteSpace(msg)) // this is usually received when the process is connection is closed (e.g. process has existed)\n                    {\n                        _watchProcessHealthCancellationTokenSource.Cancel();\n                        break;\n                    }\n                    Trace.TraceError(\n                        $\"Unexpected message '{msg}' received from App {this.Identity} instead of heart beat\");\n                }\n                else if(!cancellationToken.IsCancellationRequested)\n                {\n                    Trace.TraceError($\"Heart beat has not been received in time from {this.Identity}; App is unhealthy\");\n                }\n            }\n        }\n\n        private async Task StopMonitoringProcessHealth()\n        {\n            if (_watchProcessHealthCancellationTokenSource != null && !_watchProcessHealthCancellationTokenSource.IsCancellationRequested)\n            {\n                _watchProcessHealthCancellationTokenSource.Cancel();\n            }\n            if (_watchProcessHealthTask != null)\n            {\n                await _watchProcessHealthTask;\n            }\n\n            _watchProcessHealthCancellationTokenSource?.Dispose();\n            _watchProcessHealthCancellationTokenSource = null;\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Process/IProcess.cs",
    "content": "using System;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Process\n{\n    public interface IProcess : IDisposable\n    {\n        Task Start(string args);\n\n        Task Close();\n\n        Task Kill();\n\n        Task ReleaseResources();\n\n        bool HasExited { get; }\n\n        bool IsRunning { get; }\n\n        event EventHandler<ProcessExitedArgs> Exited;\n\n        string ExePath { get; }\n    }\n\n    public class ProcessExitedArgs : EventArgs\n    {\n        public ProcessExitedArgs(string message)\n        {\n            Message = message;\n        }\n\n        public string Message { get; private set; }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Process/IProcessFactory.cs",
    "content": "﻿using Etg.Yams.Application;\n\nnamespace Etg.Yams.Process\n{\n    public interface IProcessFactory\n    {\n        IProcess CreateProcess(AppIdentity identity, string exePath, bool monitorInitialization, bool monitorHealth, bool gracefulShutdown);\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Process/IProcessStopper.cs",
    "content": "﻿using System.Threading.Tasks;\n\nnamespace Etg.Yams.Process\n{\n    public interface IProcessStopper\n    {\n        Task StopProcess(IProcess process);\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Process/MonitorInitProcessDecorator.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\nusing Etg.Yams.Utils;\nusing Etg.Yams.Ipc;\nusing Etg.Yams.Application;\n\nnamespace Etg.Yams.Process\n{\n    public class MonitorInitProcessDecorator : AbstractProcessDecorator\n    {\n        private readonly YamsConfig _config;\n        private readonly IIpcConnection _ipcConnection;\n\n        public MonitorInitProcessDecorator(AppIdentity identity, YamsConfig config, IProcess process,\n            IIpcConnection ipcConnection) : base(identity, process)\n        {\n            _config = config;\n            _ipcConnection = ipcConnection;\n        }\n\n        public override void Dispose()\n        {\n            base.Dispose();\n            _ipcConnection?.Dispose();\n        }\n\n        public override async Task Start(string args)\n        {\n            await _process.Start($\"{args} --InitializationPipeName {_ipcConnection.ConnectionId}\");\n\n            try\n            {\n                await _ipcConnection.Connect().Timeout(_config.IpcConnectTimeout,\n                    $\"Connecting to initialization pipe has timed out, make sure that the app {this.Identity} is connecting to the same pipe\");\n\n                Trace.TraceInformation($\"Yams is waiting for the app {this.Identity} to finish initializing\");\n                string msg = await _ipcConnection.ReadMessage()\n                    .Timeout(_config.AppInitTimeout, $\"Did not receive initialized message from the app {ExePath}\");\n\n                if (msg != \"[INITIALIZE_DONE]\")\n                {\n                    throw new InvalidOperationException($\"Unexpected message '{msg}' received from app {this.Identity}\");\n                }\n            }\n            catch (Exception)\n            {\n                await Kill();\n                throw;\n            }\n\n            Trace.TraceInformation($\"Received initialized message from App {this.Identity}; App is ready to receive requests\");\n        }\n\n        public override async Task Kill()\n        {\n            await Task.WhenAll(_ipcConnection.Disconnect(), base.Kill());\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Process/Process.cs",
    "content": "﻿using Etg.Yams.Application;\nusing Etg.Yams.Os;\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Process\n{\n    /// <summary>\n    /// A Wrapper around the <see cref=\"System.Diagnostics.Process\"/>.\n    /// </summary>\n    public class Process : IProcess\n    {\n        private readonly AppIdentity _identity;\n        private readonly string _exePath;\n        private readonly bool _useShellExecute;\n        private readonly ISystem system;\n        private System.Diagnostics.Process _process;\n        private bool _isRunning = false;\n\n        public bool IsRunning\n        {\n            get\n            {\n                if (_process == null)\n                    return false;\n                if (_process.HasExited)\n                    return false;\n                return _isRunning;\n            }\n        }\n\n        public event EventHandler<ProcessExitedArgs> Exited;\n\n        public Process(AppIdentity identity, string exePath, bool useShellExecute, ISystem system)\n        {\n            _identity = identity;\n            _exePath = exePath;\n            _useShellExecute = useShellExecute;\n            this.system = system;\n        }\n\n        public async Task Start(string args)\n        {\n            if (_isRunning)\n            {\n                throw new Exception($\"{_identity} Cannot start a process that is already running\");\n            }\n            ExeArgs = $\"{args} --AppName {_identity.Id} --AppVersion {_identity.Version}\";\n            await Task.Run(async () =>\n            {\n                _process = new System.Diagnostics.Process\n                {\n                    StartInfo = new ProcessStartInfo\n                    {\n                        UseShellExecute = _useShellExecute,\n                        FileName = _exePath,\n                        WorkingDirectory = new FileInfo(_exePath).Directory.FullName,\n                        WindowStyle = ProcessWindowStyle.Normal,\n                        Arguments = ExeArgs\n                    },\n                    EnableRaisingEvents = true,\n                };\n                _process.Exited += ProcessExited;\n\n                if (!_useShellExecute)\n                {\n                    _process.StartInfo.EnvironmentVariables[\"PATH\"] = system.GetPathEnvironmentVariable();\n                }\n\n                Trace.TraceInformation($\"Starting Process with ExePath {_exePath}, arguments: {ExeArgs}\");\n                if (!_process.Start())\n                {\n                    await ReleaseResources();\n                    throw new Exception(\n                        $\"{_identity} The OS failed to start the process at {_exePath} with arguments {ExeArgs}\");\n                }\n\n                _isRunning = true;\n                Trace.TraceInformation($\"Process started: ExePath {_exePath}, arguments: {ExeArgs}\");\n            });\n        }\n\n    public async Task Close()\n        {\n            if (_process == null) return;\n\n            _process.Exited -= ProcessExited;\n            await Task.Run(() =>\n            {\n                //TODO: Use Process.WaitForExit to wait for the process to exit\n                _isRunning = _process.CloseMainWindow();\n            });\n        }\n\n        public Task Kill()\n        {\n            if (_process == null) return Task.FromResult(true);\n\n            _process.Exited -= ProcessExited;\n            return Task.Run(() =>\n            {\n                //TODO: Use Process.WaitForExit to wait for the process to exit\n                _process.Kill();\n                _isRunning = false;\n            });\n        }\n\n        public bool HasExited => _process.HasExited;\n\n        protected void ProcessExited(object sender, EventArgs e)\n        {\n            _isRunning = false;\n            var handler = Exited;\n            if (handler == null)\n            {\n                return;\n            }\n            string msg = $\"{_identity} The process {_exePath} has exited with exit code {_process.ExitCode}\";\n            Trace.TraceInformation(msg);\n            handler(this, new ProcessExitedArgs(msg));\n        }\n\n        public async Task ReleaseResources()\n        {\n            if (IsRunning)\n            {\n                throw new Exception($\"{_identity} You should stop the process before releasing resources\");\n            }\n            _isRunning = false;\n            if (_process != null)\n            {\n                await Task.Run(() =>\n                {\n                    _process.Exited -= ProcessExited;\n                    _process.Dispose();\n                    _process = null;\n                });\n            }\n        }\n\n        public string ExePath => _exePath;\n        public string ExeArgs { get; private set; }\n\n        public void Dispose()\n        {\n            Kill().Wait();\n            ReleaseResources().Wait();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Process/ProcessFactory.cs",
    "content": "﻿using Etg.Yams.Application;\nusing Etg.Yams.Ipc;\nusing Etg.Yams.Os;\nusing System;\n\nnamespace Etg.Yams.Process\n{\n    public class ProcessFactory : IProcessFactory\n    {\n        private readonly YamsConfig _config;\n        private readonly ISystem system;\n\n        public ProcessFactory(YamsConfig config, ISystem system)\n        {\n            _config = config;\n            this.system = system;\n        }\n\n        public IProcess CreateProcess(AppIdentity identity, string exePath, bool monitorInitialization, bool monitorHealth,\n            bool gracefulShutdown)\n        {\n            IProcess process = new Process(identity, exePath, _config.UseShellExecute, system);\n\n            if (monitorInitialization)\n            {\n                string pipeName = Guid.NewGuid().ToString();\n                process = new MonitorInitProcessDecorator(identity, _config, process,\n                    new IpcConnection(new NamedPipeServerAdapter(pipeName)));\n            }\n            if (gracefulShutdown)\n            {\n                string pipeName = Guid.NewGuid().ToString();\n                process = new GracefulShutdownProcessDecorator(identity, _config, process,\n                    new IpcConnection(new NamedPipeServerAdapter(pipeName)));\n            }\n            if (monitorHealth)\n            {\n                string pipeName = Guid.NewGuid().ToString();\n                process = new HealthProcessDecorator(identity, _config, process,\n                    new IpcConnection(new NamedPipeServerAdapter(pipeName)));\n            }\n            return new SelfRestartingProcess(process, _config.ApplicationRestartCount);\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Process/ProcessStopper.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\nusing Etg.Yams.Utils;\n\nnamespace Etg.Yams.Process\n{\n    public class ProcessStopper : IProcessStopper\n    {\n        private const int ReleaseResourcesDelayMilliseconds = 5000;\n\n        private readonly int _waitForExitInSeconds;\n\n        public ProcessStopper(int waitForExitInSeconds)\n        {\n            _waitForExitInSeconds = waitForExitInSeconds;\n        }\n\n        public async Task StopProcess(IProcess process)\n        {\n            string exePath = process.ExePath;\n            try\n            {\n                if (!await Close(process))\n                {\n                    Trace.TraceInformation(\"The host process would not close, attempting to kill\");\n                    await process.Kill();\n                    Trace.TraceInformation(\"The host process was killed\");\n                }\n                else\n                {\n                    Trace.TraceInformation(\"Process Closed\");\n                }\n\n                await process.ReleaseResources();\n                await Task.Delay(ReleaseResourcesDelayMilliseconds); // allowing the os some time to release resources\n            }\n            catch (Exception ex)\n            {\n                // there is nothing more we can do; we'll swallow the exception and log an error\n                Trace.TraceError(\"{0} host process could not be killed. Exception was: {1}\", exePath, ex);\n            }\n        }\n\n        private async Task<bool> Close(IProcess process)\n        {\n            try\n            {\n                await process.Close();\n                return await ProcessUtils.SpinWaitForExit(process, _waitForExitInSeconds);\n            }\n            catch (Exception e)\n            {\n                Trace.TraceError($\"Failed to close process {process.ExePath}, Exception: {e}\");\n                return false;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Process/SelfRestartingProcess.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Process\n{\n    /// <summary>\n    /// A process that automatically restarts itself if it exists unexpectedly (for a finite number of trials).\n    /// If <see cref=\"Close\"/> or <see cref=\"Kill\"/> is called, the process won't attempt to restart itself.\n    /// </summary>\n    public class SelfRestartingProcess : IProcess\n    {\n        private bool _stopped = false;\n        private int _restartCount=0;\n        private readonly IProcess _process;\n        private readonly int _maximumRestartAttempts;\n\n        public bool IsRunning\n        {\n            get { return _process.IsRunning; }\n        }\n\n        public event EventHandler<ProcessExitedArgs> Exited;\n\n        public SelfRestartingProcess(IProcess process, int maximumRestartAttempts)\n        {\n            _process = process;\n            _maximumRestartAttempts = maximumRestartAttempts;\n        }\n\n        public Task Start(string args)\n        {\n            _process.Exited += (s, e) => ExitedTryRestart(s, e, args);\n            _stopped = false;\n            return _process.Start(args);\n        }\n\n        public Task Close()\n        {\n            _stopped = true;\n            return _process.Close();\n        }\n\n        public Task Kill()\n        {\n            _stopped = true;\n            return _process.Kill();\n        }\n\n        public Task ReleaseResources()\n        {\n            return _process.ReleaseResources();\n        }\n\n        public bool HasExited\n        {\n            get { return _process.HasExited; }\n        }\n\n        public int RestartCount \n        {\n            get { return _restartCount;}\n        }\n\n        protected async void ExitedTryRestart(object sender, ProcessExitedArgs args, string exeArgs)\n        {\n            // _stopped indicates if the process has been manually stopped; in which case, it should not be restarted.\n            if (_stopped) return;\n            Trace.TraceInformation(\"Host process exited, will attempt a restart.\");\n            await _process.ReleaseResources();\n\n            if (_restartCount >= _maximumRestartAttempts)\n            {\n                OnFailed(\"Process {0} has exited {1} times and won't be restarted; failure message {2}\", _process.ExePath, _restartCount, args.Message);\n            }\n            else\n            {\n                try\n                {\n                    await _process.Start(exeArgs);\n                    ++_restartCount;\n                }\n                catch (Exception)\n                {\n                    OnFailed(\"Process {0} has exited and could not be restarted; failure message {1}\", _process.ExePath, args.Message);\n                }\n            }\n        }\n\n        protected void OnFailed(string format, params object[] args)\n        {\n            Trace.TraceWarning(format, args);\n            var failedEvent = Exited;\n            if (failedEvent == null) return;\n            failedEvent(this, new ProcessExitedArgs(string.Format(format, args)));\n        }\n\n        public string ExePath\n        {\n            get { return _process.ExePath; }\n        }\n\n        public void Dispose()\n        {\n            _process.Dispose();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Etg.Yams.Core\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Etg.Yams.Core\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"7145e485-34fa-4632-89b0-bd27c96af69c\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/BinariesNotFoundException.cs",
    "content": "﻿using System;\n\nnamespace Etg.Yams.Storage\n{\n    public class BinariesNotFoundException : Exception\n    {\n        public BinariesNotFoundException()\n        {\n        }\n\n        public BinariesNotFoundException(string msg) : base(msg)\n        {\n        }\n\n        public BinariesNotFoundException(string msg, Exception ex) : base(msg, ex)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Config/AppDeploymentConfig.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing Etg.Yams.Application;\nusing Etg.Yams.Install;\nusing Etg.Yams.Utils;\n\nnamespace Etg.Yams.Storage.Config\n{\n    public class AppDeploymentConfig : AppInstallConfig\n    {\n        public AppDeploymentConfig(AppIdentity appIdentity) : base(appIdentity)\n        {\n            TargetClusters = new HashSet<string>();\n        }\n\n        public AppDeploymentConfig(AppIdentity appIdentity, IEnumerable<string> targetClusters,\n            IReadOnlyDictionary<string, string> properties) : base(appIdentity, properties)\n        {\n            TargetClusters = new HashSet<string>(targetClusters);\n        }\n\n        public AppDeploymentConfig(AppIdentity appIdentity, IEnumerable<string> clustersIds) : this(appIdentity, clustersIds,\n            new Dictionary<string, string>())\n        {\n        }\n\n        public AppDeploymentConfig AddClusterId(string clusterId)\n        {\n            if (TargetClusters.Contains(clusterId))\n            {\n                return this;\n            }\n            var clusterIds = new HashSet<string>(TargetClusters) {clusterId};\n            return new AppDeploymentConfig(AppIdentity, clusterIds, Properties);\n        }\n\n        public AppDeploymentConfig RemoveClusterId(string clusterId)\n        {\n            if (!TargetClusters.Contains(clusterId))\n            {\n                return this;\n            }\n            var clusterIds = TargetClusters.Where(c => c != clusterId);\n            return new AppDeploymentConfig(AppIdentity, clusterIds, Properties);\n        }\n\n        public AppDeploymentConfig AddProperty(string key, string value)\n        {\n            if (Properties.ContainsKey(key))\n            {\n                return this;\n            }\n            Dictionary<string, string> dict = Properties.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);\n            dict[key] = value;\n            return new AppDeploymentConfig(AppIdentity, TargetClusters, dict);\n        }\n\n        public AppDeploymentConfig RemoveProperty(string key)\n        {\n            if (!Properties.ContainsKey(key))\n            {\n                return this;\n            }\n            Dictionary<string, string> dict = Properties.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);\n            dict.Remove(key);\n            return new AppDeploymentConfig(AppIdentity, TargetClusters, dict);\n        }\n\n        protected new bool Equals(AppDeploymentConfig other)\n        {\n            return base.Equals(other) && (new HashSet<string>(TargetClusters).SetEquals(other.TargetClusters));\n        }\n\n        public override bool Equals(object obj)\n        {\n            if (ReferenceEquals(null, obj)) return false;\n            if (ReferenceEquals(this, obj)) return true;\n            if (obj.GetType() != this.GetType()) return false;\n            return Equals((AppDeploymentConfig) obj);\n        }\n\n        public override int GetHashCode()\n        {\n            unchecked\n            {\n                int hashCode = (base.GetHashCode()*397) ^ (TargetClusters != null ? HashCodeUtils.GetHashCode(TargetClusters) : 0);\n                return hashCode;\n            }\n        }\n\n        public static bool operator ==(AppDeploymentConfig left, AppDeploymentConfig right)\n        {\n            return Equals(left, right);\n        }\n\n        public static bool operator !=(AppDeploymentConfig left, AppDeploymentConfig right)\n        {\n            return !Equals(left, right);\n        }\n\n        public IEnumerable<string> TargetClusters { get; }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Config/DeploymentConfig.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Etg.Yams.Application;\nusing Etg.Yams.Utils;\n\nnamespace Etg.Yams.Storage.Config\n{\n    public class DeploymentConfig : IEnumerable<AppDeploymentConfig>\n    {\n        private readonly Dictionary<AppIdentity, AppDeploymentConfig> _apps = new Dictionary<AppIdentity, AppDeploymentConfig>();\n\n        public DeploymentConfig()\n        {\n        }\n\n        public DeploymentConfig(IEnumerable<AppDeploymentConfig> apps)\n        {\n            _apps = new HashSet<AppDeploymentConfig>(apps).ToDictionary(config => config.AppIdentity, config => config);\n        }\n\n        private DeploymentConfig(Dictionary<AppIdentity, AppDeploymentConfig> apps)\n        {\n            _apps = apps;\n        }\n\n        protected bool Equals(DeploymentConfig other)\n        {\n            return Equals(_apps, other._apps);\n        }\n\n        public override bool Equals(object obj)\n        {\n            if (ReferenceEquals(null, obj)) return false;\n            if (ReferenceEquals(this, obj)) return true;\n            if (obj.GetType() != this.GetType()) return false;\n            return Equals((DeploymentConfig) obj);\n        }\n\n        public override int GetHashCode()\n        {\n            return HashCodeUtils.GetHashCode(_apps.Values);\n        }\n\n        public IEnumerable<string> ListApplications()\n        {\n            var appIds = new HashSet<string>();\n            appIds.UnionWith(_apps.Keys.Select(identity => identity.Id));\n            return appIds;\n        }\n\n        public IEnumerable<string> ListApplications(string clusterId)\n        {\n            var appIds = new HashSet<string>();\n            appIds.UnionWith(_apps.Values.Where(config => config.TargetClusters.Contains(clusterId))\n                .Select(config => config.AppIdentity.Id));\n            return appIds;\n        }\n\n        public IEnumerable<string> ListVersions(string appId)\n        {\n            var appIds = new HashSet<string>();\n            appIds.UnionWith(_apps.Values\n                .Where(config => config.AppIdentity.Id == appId)\n                .Select(config => config.AppIdentity.Version.ToString()));\n            return appIds;\n        }\n\n        public IEnumerable<string> ListVersions(string appId, string clusterId)\n        {\n            var appIds = new HashSet<string>();\n            appIds.UnionWith(_apps.Values\n                .Where(config => config.AppIdentity.Id == appId && config.TargetClusters.Contains(clusterId))\n                .Select(config => config.AppIdentity.Version.ToString()));\n            return appIds;\n        }\n\n        public IEnumerable<string> ListClusters()\n        {\n            var clusterIds = new HashSet<string>();\n            clusterIds.UnionWith(_apps.Values.SelectMany(config => config.TargetClusters));\n            return clusterIds;\n        }\n\n        public IEnumerable<string> ListClusters(string appId)\n        {\n            var clusterIds = new HashSet<string>();\n            clusterIds.UnionWith(_apps.Values.Where(config => config.AppIdentity.Id == appId).SelectMany(config => config.TargetClusters));\n            return clusterIds;\n        }\n\n        public IEnumerable<string> ListClusters(AppIdentity appIdentity)\n        {\n            AppDeploymentConfig config;\n            if (!_apps.TryGetValue(appIdentity, out config))\n            {\n                return Enumerable.Empty<string>();\n            }\n            return config.TargetClusters;\n        }\n\n        public DeploymentConfig AddApplication(AppIdentity appIdentity, string clusterId)\n        {\n            AppDeploymentConfig appDeploymentConfig;\n            DeploymentConfig deploymentConfig = this;\n            if (deploymentConfig.HasApplication(appIdentity))\n            {\n                appDeploymentConfig = deploymentConfig.GetApplicationConfig(appIdentity);\n                appDeploymentConfig = appDeploymentConfig.AddClusterId(clusterId);\n                deploymentConfig = RemoveApplication(appIdentity);\n            }\n            else\n            {\n                appDeploymentConfig = new AppDeploymentConfig(appIdentity, new [] {clusterId});\n            }\n            return deploymentConfig.SetApplicationConfig(appDeploymentConfig);\n        }\n\n        public DeploymentConfig AddApplication(string appId, string version, string clusterId)\n        {\n            return AddApplication(new AppIdentity(appId, version), clusterId);\n        }\n\n        public DeploymentConfig SetApplicationConfig(AppDeploymentConfig appDeploymentConfig)\n        {\n            var apps = CopyApps();\n            apps[appDeploymentConfig.AppIdentity] = appDeploymentConfig;\n            return new DeploymentConfig(apps);\n        }\n\n        private Dictionary<AppIdentity, AppDeploymentConfig> CopyApps()\n        {\n            var apps = _apps.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);\n            return apps;\n        }\n\n        public AppDeploymentConfig GetApplicationConfig(AppIdentity appIdentity)\n        {\n            AppDeploymentConfig config;\n            if (!_apps.TryGetValue(appIdentity, out config))\n            {\n                throw new InvalidOperationException($\"App {appIdentity} doesn't exist\");\n            }\n            return config;\n        }\n\n        public bool HasApplication(string appId)\n        {\n            return _apps.Keys.Any(identity => identity.Id == appId);\n        }\n\n        public bool HasApplication(AppIdentity appIdentity)\n        {\n            return _apps.ContainsKey(appIdentity);\n        }\n\n        public bool HasApplication(AppIdentity appIdentity, string clusterId)\n        {\n            AppDeploymentConfig config;\n            if (!_apps.TryGetValue(appIdentity, out config))\n            {\n                return false;\n            }\n            return config.TargetClusters.Contains(clusterId);\n        }\n\n        public DeploymentConfig RemoveApplication(string appId)\n        {\n            if (!HasApplication(appId))\n            {\n                throw new InvalidOperationException(\"Cannot remove an application that is not there\");\n            }\n            var apps = CopyApps();\n            foreach (AppIdentity appIdentity in _apps.Keys.Where(identity => identity.Id == appId))\n            {\n                apps.Remove(appIdentity);\n            }\n            return new DeploymentConfig(apps);\n        }\n\n        public DeploymentConfig RemoveApplication(string appId, string clusterId)\n        {\n            if (!HasApplication(appId))\n            {\n                throw new InvalidOperationException(\"Cannot remove an application that is not there\");\n            }\n            var apps = CopyApps();\n            foreach (AppDeploymentConfig config in _apps.Values.Where(config => config.AppIdentity.Id == appId))\n            {\n                if (!config.TargetClusters.Contains(clusterId))\n                {\n                    continue;\n                }\n                var newConfig = config.RemoveClusterId(clusterId);\n                if (newConfig.TargetClusters.Any())\n                {\n                    apps[config.AppIdentity] = newConfig;\n                }\n                else\n                {\n                    apps.Remove(config.AppIdentity);\n                }\n            }\n            return new DeploymentConfig(apps);\n        }\n\n        public DeploymentConfig RemoveApplication(AppIdentity appIdentity)\n        {\n            if (!_apps.ContainsKey(appIdentity))\n            {\n                throw new InvalidOperationException(\"Cannot remove an application that is not there\");\n            }\n            var apps = CopyApps();\n            apps.Remove(appIdentity);\n            return new DeploymentConfig(apps);\n        }\n\n        public DeploymentConfig RemoveApplication(AppIdentity appIdentity, string clusterId)\n        {\n            AppDeploymentConfig config;\n            if (!_apps.TryGetValue(appIdentity, out config))\n            {\n                throw new InvalidOperationException(\"Cannot remove an application that is not there\");\n            }\n            config = config.RemoveClusterId(clusterId);\n\n            var apps = CopyApps();\n            apps.Remove(appIdentity);\n            if (config.TargetClusters.Any())\n            {\n                apps[appIdentity] = config;\n            }\n            return new DeploymentConfig(apps);\n        }\n\n        public IEnumerator<AppDeploymentConfig> GetEnumerator()\n        {\n            return _apps.Values.GetEnumerator();\n        }\n\n        IEnumerator IEnumerable.GetEnumerator()\n        {\n            return GetEnumerator();\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Config/IDeploymentConfigSerializer.cs",
    "content": "namespace Etg.Yams.Storage.Config\n{\n    public interface IDeploymentConfigSerializer\n    {\n        DeploymentConfig Deserialize(string data);\n        string Serialize(DeploymentConfig deploymentConfig);\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Config/JsonDeploymentConfigSerializer.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing Etg.Yams.Application;\nusing Etg.Yams.Json;\n\nnamespace Etg.Yams.Storage.Config\n{\n    public class JsonDeploymentConfigSerializer : IDeploymentConfigSerializer\n    {\n        private readonly IJsonSerializer _jsonSerializer;\n\n        public JsonDeploymentConfigSerializer(IJsonSerializer jsonSerializer)\n        {\n            _jsonSerializer = jsonSerializer;\n        }\n\n        public DeploymentConfig Deserialize(string data)\n        {\n            DeploymentConfig deploymentConfig = new DeploymentConfig();\n            Dictionary<string, AppDeploymentConfig> apps = new Dictionary<string, AppDeploymentConfig>();\n            if (string.IsNullOrEmpty(data))\n            {\n                return deploymentConfig;\n            }\n\n            var appDeploymentConfigs = new List<AppDeploymentConfig>();\n            ApplicationsData appsData = _jsonSerializer.Deserialize<ApplicationsData>(data);\n            foreach (ApplicationData appData in appsData.Applications)\n            {\n                AppIdentity appIdentity = new AppIdentity(appData.Id, appData.Version);\n                AppDeploymentConfig appDeploymentConfig \n                    = new AppDeploymentConfig(appIdentity, appData.TargetClusters, appData.Properties);\n                appDeploymentConfigs.Add(appDeploymentConfig);\n            }\n            return new DeploymentConfig(appDeploymentConfigs);\n        }\n\n        public string Serialize(DeploymentConfig deploymentConfig)\n        {\n            var applicationsList = new List<ApplicationData>();\n            foreach (AppDeploymentConfig appDeploymentConfig in deploymentConfig)\n            {\n                applicationsList.Add(new ApplicationData(appDeploymentConfig.AppIdentity.Id, \n                    appDeploymentConfig.AppIdentity.Version.ToString(), appDeploymentConfig.TargetClusters.ToArray(), \n                    appDeploymentConfig.Properties.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)));\n            }\n            ApplicationsData applicationsData = new ApplicationsData(applicationsList.ToArray());\n            return _jsonSerializer.Serialize(applicationsData);\n        }\n\n        private class ApplicationData\n        {\n            public ApplicationData(string id, string version, string[] targetClusters, Dictionary<string, string> properties)\n            {\n                Id = id;\n                Version = version;\n                TargetClusters = targetClusters;\n                if (properties != null)\n                {\n                    Properties = properties;\n                }\n                else\n                {\n                    Properties = new Dictionary<string, string>();\n                }\n                \n            }\n\n            public string Id { get; private set; }\n            public string Version { get; private set; }\n            public string[] TargetClusters { get; private set; }\n            public Dictionary<string, string> Properties { get; private set; }\n        }\n\n        private class ApplicationsData\n        {\n            public ApplicationsData(ApplicationData[] applications)\n            {\n                Applications = applications;\n            }\n\n            public ApplicationData[] Applications { get; private set; }\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/ConflictResolutionMode.cs",
    "content": "﻿namespace Etg.Yams.Storage\n{\n    public enum ConflictResolutionMode\n    {\n        DoNothingIfBinariesExist,\n        FailIfBinariesExist,\n        OverwriteExistingBinaries\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/DuplicateBinariesException.cs",
    "content": "﻿using System;\n\nnamespace Etg.Yams.Storage\n{\n    public class DuplicateBinariesException : Exception\n    {\n        public DuplicateBinariesException()\n        {\n        }\n\n        public DuplicateBinariesException(string msg) : base(msg)\n        {\n        }\n\n        public DuplicateBinariesException(string msg, Exception ex) : base(msg, ex)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/IDeploymentRepository.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Storage\n{\n    public interface IDeploymentRepository\n    {\n        Task<DeploymentConfig> FetchDeploymentConfig();\n        Task PublishDeploymentConfig(DeploymentConfig deploymentConfig);\n        Task UploadApplicationBinaries(AppIdentity appIdentity, string localPath, ConflictResolutionMode conflictResolutionMode);\n        Task DeleteApplicationBinaries(AppIdentity appIdentity);\n        Task<bool> HasApplicationBinaries(AppIdentity appIdentity);\n        Task DownloadApplicationBinaries(AppIdentity appIdentity, string localPath, ConflictResolutionMode conflictResolutionMode);\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/IDeploymentStatusReader.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Storage.Status;\n\nnamespace Etg.Yams.Storage\n{\n    public interface IDeploymentStatusReader\n    {\n        Task<InstanceDeploymentStatus> FetchInstanceDeploymentStatus(string clusterId, string instanceId);\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/IDeploymentStatusWriter.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Storage.Status;\n\nnamespace Etg.Yams.Storage\n{\n    public interface IDeploymentStatusWriter\n    {\n        Task PublishInstanceDeploymentStatus(string clusterId, string instanceId,\n            InstanceDeploymentStatus instanceDeploymentStatus);\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Status/AppDeploymentStatus.cs",
    "content": "﻿using Etg.Yams.Application;\nusing Newtonsoft.Json;\nusing Semver;\nusing System;\n\nnamespace Etg.Yams.Storage.Status\n{\n    public class AppDeploymentStatus\n    {\n        public AppDeploymentStatus(AppIdentity appIdentity, string clusterId, string instanceId, \n            DateTime utcTimeStamp)\n        {\n            AppIdentity = appIdentity;\n            ClusterId = clusterId;\n            InstanceId = instanceId;\n            UtcTimeStamp = utcTimeStamp;\n        }\n\n        [JsonConstructor]\n        public AppDeploymentStatus(string id, string version, string clusterId, string instanceId, \n            DateTime utcTimeStamp) : this(new AppIdentity(id, version), clusterId, instanceId, utcTimeStamp)\n        {\n        }\n\n        [JsonIgnore]\n        public AppIdentity AppIdentity { get; private set; }\n\n        public string Id => AppIdentity.Id;\n        public string Version => AppIdentity.Version.ToString();\n        public string ClusterId { get; }\n        public string InstanceId { get; private set; }\n        public DateTime UtcTimeStamp { get; }\n\n        private AppDeploymentStatus Clone()\n        {\n            return new AppDeploymentStatus(AppIdentity, ClusterId, InstanceId, DateTime.UtcNow);\n        }\n\n        private AppDeploymentStatus WithVersion(SemVersion version)\n        {\n            var appDeploymentStatus = Clone();\n            appDeploymentStatus.AppIdentity = new AppIdentity(appDeploymentStatus.AppIdentity.Id, version);\n            return appDeploymentStatus;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Status/ClusterDeploymentStatus.cs",
    "content": "﻿using Etg.Yams.Application;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Etg.Yams.Storage.Status\n{\n    public class ClusterDeploymentStatus : IEnumerable<AppDeploymentStatus>\n    {\n        readonly Dictionary<string, InstanceDeploymentStatus> _instances = new Dictionary<string, InstanceDeploymentStatus>();\n\n        public AppDeploymentStatus GetAppDeploymentStatus(string instanceId, AppIdentity appIdentity)\n        {\n            InstanceDeploymentStatus instanceDeploymentStatus;\n            if (!_instances.TryGetValue(instanceId, out instanceDeploymentStatus))\n            {\n                return null;\n            }\n            return instanceDeploymentStatus.GetAppDeploymentStatus(appIdentity);\n        }\n\n        public void SetAppDeploymentStatus(AppDeploymentStatus appDeploymentStatus)\n        {\n            InstanceDeploymentStatus instanceDeploymentStatus;\n            if (!_instances.TryGetValue(appDeploymentStatus.InstanceId, out instanceDeploymentStatus))\n            {\n                instanceDeploymentStatus = new InstanceDeploymentStatus();\n                _instances[appDeploymentStatus.InstanceId] = instanceDeploymentStatus;\n            }\n            instanceDeploymentStatus.SetAppDeploymentStatus(appDeploymentStatus);\n        }\n\n        public void SetInstanceDeploymentStatus(string instanceId, InstanceDeploymentStatus status)\n        {\n            _instances[instanceId] = status;\n        }\n\n        public IEnumerable<AppDeploymentStatus> ListAll()\n        {\n            return _instances.Values.SelectMany(instance => instance.Applications);\n        }\n\n        public IEnumerator<AppDeploymentStatus> GetEnumerator()\n        {\n            return ListAll().GetEnumerator();\n        }\n\n        IEnumerator IEnumerable.GetEnumerator()\n        {\n            return GetEnumerator();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Status/DeploymentStatus.cs",
    "content": "﻿using Etg.Yams.Application;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Etg.Yams.Storage.Status\n{\n    public class DeploymentStatus : IEnumerable<AppDeploymentStatus>\n    {\n        private readonly Dictionary<string, ClusterDeploymentStatus> _clusters = new Dictionary<string, ClusterDeploymentStatus>();\n\n        public IEnumerable<string> ClustersIds => _clusters.Keys;\n\n        public DeploymentStatus()\n        {\n        }\n        public DeploymentStatus(IEnumerable<AppDeploymentStatus> apps)\n        {\n            foreach(AppDeploymentStatus appDeploymentStatus in apps)\n            {\n                SetAppDeploymentStatus(appDeploymentStatus);\n            }\n        }\n\n        public void SetClusterDeploymentStatus(string clusterId, ClusterDeploymentStatus clusterDeploymentStatus)\n        {\n            _clusters[clusterId] = clusterDeploymentStatus;\n        }\n\n        public AppDeploymentStatus GetAppDeploymentStatus(string clusterId, string instanceId, AppIdentity appIdentity)\n        {\n            ClusterDeploymentStatus clusterDeploymentStatus;\n            if (!_clusters.TryGetValue(clusterId, out clusterDeploymentStatus))\n            {\n                return null;\n            }\n            return clusterDeploymentStatus.GetAppDeploymentStatus(instanceId, appIdentity);\n        }\n\n        public void SetAppDeploymentStatus(AppDeploymentStatus appDeploymentStatus)\n        {\n            ClusterDeploymentStatus clusterDeploymentStatus;\n            if (!_clusters.TryGetValue(appDeploymentStatus.ClusterId, out clusterDeploymentStatus))\n            {\n                clusterDeploymentStatus = new ClusterDeploymentStatus();\n                _clusters[appDeploymentStatus.ClusterId] = clusterDeploymentStatus;\n            }\n            clusterDeploymentStatus.SetAppDeploymentStatus(appDeploymentStatus);\n        }\n\n        public ClusterDeploymentStatus GetClusterDeploymentStatus(string clusterId)\n        {\n            ClusterDeploymentStatus clusterDeploymentStatus;\n            if (!_clusters.TryGetValue(clusterId, out clusterDeploymentStatus))\n            {\n                return null;\n            }\n            return clusterDeploymentStatus;\n        }\n\n        public IEnumerable<AppDeploymentStatus> ListAll()\n        {\n            return _clusters.Values.SelectMany(cluster => cluster.ListAll());\n        }\n\n        public IEnumerator<AppDeploymentStatus> GetEnumerator()\n        {\n            return ListAll().GetEnumerator();\n        }\n\n        IEnumerator IEnumerable.GetEnumerator()\n        {\n            return GetEnumerator();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Status/IDeploymentStatusSerializer.cs",
    "content": "﻿namespace Etg.Yams.Storage.Status\n{\n    public interface IDeploymentStatusSerializer\n    {\n        InstanceDeploymentStatus Deserialize(string data);\n        string Serialize(InstanceDeploymentStatus instanceDeploymentStatus);\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Status/InstanceDeploymentStatus.cs",
    "content": "﻿using Etg.Yams.Application;\nusing System.Collections.Generic;\nusing Newtonsoft.Json;\n\nnamespace Etg.Yams.Storage.Status\n{\n    public class InstanceDeploymentStatus\n    {\n        private readonly Dictionary<AppIdentity, AppDeploymentStatus> _apps = new Dictionary<AppIdentity, AppDeploymentStatus>();\n\n        public InstanceDeploymentStatus()\n        {\n        }\n\n        [JsonConstructor]\n        public InstanceDeploymentStatus(IEnumerable<AppDeploymentStatus> applications)\n        {\n            if (applications == null)\n            {\n                return;\n            }\n            foreach (AppDeploymentStatus appDeploymentStatus in applications)\n            {\n                SetAppDeploymentStatus(appDeploymentStatus);\n            }\n        }\n\n        public IEnumerable<AppDeploymentStatus> Applications =>_apps.Values;\n\n        public AppDeploymentStatus GetAppDeploymentStatus(AppIdentity appIdentity)\n        {\n            AppDeploymentStatus appDeploymentStatus;\n            if (!_apps.TryGetValue(appIdentity, out appDeploymentStatus))\n            {\n                return null;\n            }\n            return appDeploymentStatus;\n        }\n\n        public void SetAppDeploymentStatus(AppDeploymentStatus appDeploymentStatus)\n        {\n            _apps[appDeploymentStatus.AppIdentity] = appDeploymentStatus;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Storage/Status/JsonDeploymentStatusSerializer.cs",
    "content": "﻿using Etg.Yams.Json;\nusing System.Collections.Generic;\n\nnamespace Etg.Yams.Storage.Status\n{\n    public class JsonDeploymentStatusSerializer : IDeploymentStatusSerializer\n    {\n        private readonly IJsonSerializer _jsonSerializer;\n\n        public JsonDeploymentStatusSerializer(IJsonSerializer jsonSerializer)\n        {\n            _jsonSerializer = jsonSerializer;\n        }\n\n        public InstanceDeploymentStatus Deserialize(string data)\n        {\n            if (data == null)\n            {\n                return new InstanceDeploymentStatus();\n            }\n            return _jsonSerializer.Deserialize<InstanceDeploymentStatus>(data);\n        }\n\n        public string Serialize(InstanceDeploymentStatus instanceDeploymentStatus)\n        {\n            return _jsonSerializer.Serialize(instanceDeploymentStatus);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Update/ApplicationUpdateManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Deploy;\nusing Etg.Yams.Download;\nusing Etg.Yams.Install;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Utils;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Status;\n\nnamespace Etg.Yams.Update\n{\n    public class ApplicationUpdateManager : IApplicationUpdateManager\n    {\n        private readonly string _clusterId;\n        private readonly string _instanceId;\n        private readonly IApplicationDeploymentDirectory _applicationDeploymentDirectory;\n        private readonly IApplicationPool _applicationPool;\n        private readonly IApplicationDownloader _applicationDownloader;\n        private readonly IApplicationInstaller _applicationInstaller;\n        private readonly IDeploymentStatusWriter _deploymentStatusWriter;\n        private readonly IUpdateSessionManager _updateSessionManager;\n\n        public ApplicationUpdateManager(\n            string clusterId,\n            string instanceId,\n            IApplicationDeploymentDirectory applicationDeploymentDirectory,\n            IApplicationPool applicationPool, \n            IApplicationDownloader applicationDownloader, \n            IApplicationInstaller applicationInstaller,\n            IDeploymentStatusWriter deploymentStatusWriter,\n            IUpdateSessionManager updateSessionManager)\n        {\n            _clusterId = clusterId;\n            this._instanceId = instanceId;\n            _applicationDeploymentDirectory = applicationDeploymentDirectory;\n            _applicationPool = applicationPool;\n            _applicationDownloader = applicationDownloader;\n            _applicationInstaller = applicationInstaller;\n            _deploymentStatusWriter = deploymentStatusWriter;\n            _updateSessionManager = updateSessionManager;\n        }\n\n        public async Task CheckForUpdates()\n        {\n            try\n            {\n                Trace.TraceInformation(\"Checking for updates\");\n\n                IEnumerable<AppDeploymentConfig> applicationDeployments = await _applicationDeploymentDirectory.FetchDeployments();\n                IEnumerable<AppIdentity> runningApplications = _applicationPool.Applications.Select(app => app.Identity).ToList();\n\n                IEnumerable<AppIdentity> applicationsToRemove = FindApplicationsToRemove(runningApplications, applicationDeployments);\n                IEnumerable<AppDeploymentConfig> applicationsToDeploy = FindApplicationsToDeploy(runningApplications, applicationDeployments);\n\n                if (!applicationsToDeploy.Any() && !applicationsToRemove.Any())\n                {\n                    return;\n                }\n\n                // download applications first\n                await DownloadApplications(applicationsToDeploy);\n\n                var allAppsIds = new HashSet<string>(applicationsToRemove.Select(identity => identity.Id));\n                allAppsIds.UnionWith(applicationsToDeploy.Select(config => config.AppIdentity.Id));\n\n                if (!await _updateSessionManager.TryStartUpdateSession())\n                {\n                    Trace.TraceInformation(\"Couldn't start update session\");\n                    return;\n                }\n\n                var tasks = new List<Task>();\n                \n                foreach (string appId in allAppsIds)\n                {\n                    IEnumerable<AppIdentity> appRemovals = applicationsToRemove.Where(identity => identity.Id.Equals(appId));\n                    IEnumerable<AppDeploymentConfig> appDeployments = applicationsToDeploy.Where(config => config.AppIdentity.Id.Equals(appId));\n\n                    // if an application has a removal(s) and deployment(s), we consider it an update\n                    if (appRemovals.Any() && appDeployments.Any())\n                    {\n                        tasks.Add(_applicationInstaller.Update(appRemovals, appDeployments));\n                    }\n                    else\n                    {\n                        foreach (AppDeploymentConfig appDeploymentConfig in appDeployments)\n                        {\n                            tasks.Add(_applicationInstaller.Install(appDeploymentConfig));\n                        }\n                        foreach (AppIdentity appRemoval in appRemovals)\n                        {\n                            tasks.Add(_applicationInstaller.UnInstall(appRemoval));\n                        }\n                    }\n                }\n                await Task.WhenAll(tasks);\n\n                // We will only end the update session if the update was successful. Otherwise, the update session will stay open and will prevent\n                // the deployment from moving to the next update domain.\n                await _updateSessionManager.EndUpdateSession(); \n            }\n            catch (AggregateException e)\n            {\n                TraceUtils.TraceAllErrors(\"Failures occured during updates\", e);\n            }\n            catch (Exception e)\n            {\n                Trace.TraceError(\"Failed to perform update; Exception: {0}\", e);\n            }\n            finally\n            {\n                await UpdateDeploymentStatus();\n            }\n        }\n\n        private async Task UpdateDeploymentStatus()\n        {\n            try\n            {\n                DateTime utcNow = DateTime.UtcNow;\n                var instanceDeploymentStatus = new InstanceDeploymentStatus();\n                foreach (IApplication app in _applicationPool.Applications)\n                {\n                    var appDeploymentStatus = new AppDeploymentStatus(app.Identity, _clusterId, _instanceId, utcNow);\n                    instanceDeploymentStatus.SetAppDeploymentStatus(appDeploymentStatus);\n                }\n                await _deploymentStatusWriter.PublishInstanceDeploymentStatus(_clusterId, _instanceId, instanceDeploymentStatus);\n                Trace.TraceInformation(\"DeploymentStatus updated\");\n            }\n            catch (Exception e)\n            {\n                Trace.TraceError(\"Failed to update the deployment status; Exception: {0}\", e);\n            }\n        }\n\n        private async Task DownloadApplications(IEnumerable<AppDeploymentConfig> appDeployments)\n        {\n            Trace.TraceInformation(\"Downloading applications\");\n            List<Task> tasks = new List<Task>();\n            foreach (AppDeploymentConfig appDeploymentConfig in appDeployments)\n            {\n                tasks.Add(_applicationDownloader.DownloadApplication(appDeploymentConfig.AppIdentity));\n            }\n            await Task.WhenAll(tasks);\n            Trace.TraceInformation(\"Download applications complete\");\n        }\n\n        private IEnumerable<AppIdentity> FindApplicationsToRemove(IEnumerable<AppIdentity> runningApplications, IEnumerable<AppDeploymentConfig> applicationDeployments)\n        {\n            ISet<AppIdentity> appIdentities = new HashSet<AppIdentity>(applicationDeployments.Select(config => config.AppIdentity));\n            return runningApplications.Where(identity => !appIdentities.Contains(identity));\n        }\n\n        private IEnumerable<AppDeploymentConfig> FindApplicationsToDeploy(IEnumerable<AppIdentity> runningApplications, IEnumerable<AppDeploymentConfig> applicationDeployments)\n        {\n            ISet<AppIdentity> runningAppsIds = new HashSet<AppIdentity>(runningApplications);\n            return applicationDeployments.Where(config => !runningAppsIds.Contains(config.AppIdentity));\n        } \n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Update/IApplicationUpdateManager.cs",
    "content": "﻿using System.Threading.Tasks;\n\nnamespace Etg.Yams.Update\n{\n    /// <summary>\n    /// Scans the remote storage to figure out if applications need to be installed, removed or updated; and performs \n    /// the corresponding work.\n    ///  </summary>\n    public interface IApplicationUpdateManager\n    {\n        Task CheckForUpdates();\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Update/IUpdateSessionManager.cs",
    "content": "﻿using System.Threading.Tasks;\n\nnamespace Etg.Yams.Update\n{\n    /// <summary>\n    /// The update session is used to preserve the notion of \"update domains\" in Azure. When an application is updated,\n    /// it will be deployed on one update domain at a time to minimize down-time. \n    /// </summary>\n    public interface IUpdateSessionManager\n    {\n        /// <summary>\n        /// Starts an update session for the current node. If any other node in a different update domain is being updated,\n        /// no session will be started and false will be returned.\n        /// </summary>\n        /// <returns>True if the session started successfully, false otherwise</returns>\n        Task<bool> TryStartUpdateSession();\n\n        /// <summary>\n        /// Ends the update session for the current node.\n        /// </summary>\n        Task EndUpdateSession();\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Utils/ApplicationUtils.cs",
    "content": "﻿using System.IO;\nusing Etg.Yams.Application;\n\nnamespace Etg.Yams.Utils\n{\n    public static class ApplicationUtils\n    {\n        public static string GetApplicationRelativePath(AppIdentity appIdentity)\n        {\n            return Path.Combine(appIdentity.Id, appIdentity.Version.ToString());\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Utils/EnvironmentUtils.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Etg.Yams.Utils\n{\n    public static class EnvironmentUtils\n    {\n        public static string GetPath(EnvironmentVariableTarget target)\n        {\n            return Environment.ExpandEnvironmentVariables(Environment.GetEnvironmentVariable(\"PATH\", target));\n        }\n\n        public static IEnumerable<string> SplitPath(string path)\n        {\n            return (path ?? string.Empty).Split(';').Where(entry => !string.IsNullOrEmpty(entry));\n        }\n\n        public static string MergePath(string processPath, string machinePath)\n        {\n            var splitProcessPath = SplitPath(processPath);\n            var splitMachinePath = SplitPath(machinePath);\n            var mergedPath = splitProcessPath.Union(splitMachinePath);\n            return string.Join(\";\", mergedPath) + \";\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Utils/ProcessUtils.cs",
    "content": "﻿using System.Diagnostics;\nusing System.Threading.Tasks;\nusing Etg.Yams.Process;\n\nnamespace Etg.Yams.Utils\n{\n    public static class ProcessUtils\n    {\n        public static async Task<bool> SpinWaitForExit(IProcess process, int maxTimeInSeconds)\n        {\n            int waitForExitInSecondsRemaining = maxTimeInSeconds;\n            Trace.TraceInformation(\"Waiting for the process to terminate\");\n            while (!process.HasExited && waitForExitInSecondsRemaining > 0)\n            {\n                await Task.Delay(1000);\n                waitForExitInSecondsRemaining--;\n            }\n            return process.HasExited;\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/Watcher/DeploymentWatcher.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing System.Timers;\nusing Etg.Yams.Update;\n\nnamespace Etg.Yams.Watcher\n{\n    public class DeploymentWatcher : IDeploymentWatcher, IDisposable\n    {\n        private readonly IApplicationUpdateManager _deploymentUpdateManager;\n        protected Timer UpdateTimer;\n        protected volatile bool IsUpdating;\n\n        public DeploymentWatcher(IApplicationUpdateManager deploymentUpdateManager, int updateFrequencyInSeconds)\n        {\n            _deploymentUpdateManager = deploymentUpdateManager;\n            IsUpdating = false;\n            UpdateTimer = new Timer(updateFrequencyInSeconds*1000);\n            UpdateTimer.Elapsed += OnTimer;\n        }\n\n        public Task Start()\n        {\n            UpdateTimer.Start();\n            return Task.FromResult(true);\n        }\n\n        public Task Stop()\n        {\n            UpdateTimer.Stop();\n            return Task.FromResult(true);\n        }\n\n        private async void OnTimer(object sender, ElapsedEventArgs args)\n        {\n            if (IsUpdating) return;\n            IsUpdating = true;\n\n            try\n            {\n                await CheckForUpdates();\n            }\n            finally\n            {\n                IsUpdating = false;\n            }\n        }\n\n        public Task CheckForUpdates()\n        {\n            return _deploymentUpdateManager.CheckForUpdates();\n        }\n\n        public void Dispose()\n        {\n            Stop().Wait();\n            UpdateTimer.Dispose();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/Watcher/IDeploymentWatcher.cs",
    "content": "﻿using System.Threading.Tasks;\n\nnamespace Etg.Yams.Watcher\n{\n    /// <summary>\n    /// Periodically check the remote storage for applications updates.\n    /// </summary>\n    public interface IDeploymentWatcher\n    {\n        Task Start();\n\n        Task Stop();\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/YamsConfig.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace Etg.Yams\n{\n    /// <summary>\n    /// Configuration parameters for YAMS.\n    /// </summary>\n    public class YamsConfig\n    {\n        public YamsConfig(\n            string superClusterId,\n            string clusterId,\n            string instanceUpdateDomain,\n            string instanceId,\n            string applicationInstallDirectory,\n            int checkForUpdatesPeriodInSeconds,\n            int applicationRestartCount,\n            int processWaitForExitInSeconds,\n            bool useShellExecute,\n            TimeSpan gracefulShutdownMessageTimeout,\n            TimeSpan appGracefulShutdownTimeout,\n            TimeSpan appHeartBeatTimeout,\n            TimeSpan ipcConnectTimeout,\n            TimeSpan appInitTimeout,\n            TimeSpan updateSessionTtl,\n            IReadOnlyDictionary<string, string> clusterProperties)\n        {\n            SuperClusterId = superClusterId;\n            ClusterId = clusterId;\n            InstanceUpdateDomain = instanceUpdateDomain;\n            InstanceId = instanceId;\n            ApplicationInstallDirectory = applicationInstallDirectory;\n            CheckForUpdatesPeriodInSeconds = checkForUpdatesPeriodInSeconds;\n            ApplicationRestartCount = applicationRestartCount;\n            ProcessWaitForExitInSeconds = processWaitForExitInSeconds;\n            UseShellExecute = useShellExecute;\n            GracefulShutdownMessageTimeout = gracefulShutdownMessageTimeout;\n            AppGracefulShutdownTimeout = appGracefulShutdownTimeout;\n            AppHeartBeatTimeout = appHeartBeatTimeout;\n            IpcConnectTimeout = ipcConnectTimeout;\n            AppInitTimeout = appInitTimeout;\n            UpdateSessionTtl = updateSessionTtl;\n            ClusterProperties = clusterProperties;\n        }\n\n        /// <summary>\n        /// An id that uniquely identifies a set of clusters (should be the same for all nodes in all clusters).\n        /// You can use the clusterId if all your nodes are in the same cluster or if your clusters are independent.\n        /// Note that the superClusterId is used by YAMS to enforce that only one update domain is active at a time;\n        /// if your nodes have different superClusterId, they will update independently.\n        /// </summary>\n        public string SuperClusterId { get; }\n\n        /// <summary>\n        /// The cluster deployment id.\n        /// </summary>\n        public string ClusterId { get; private set; }\n\n        /// <summary>\n        /// The role instance update domain.\n        /// </summary>\n        public string InstanceUpdateDomain { get; private set; }\n\n        /// <summary>\n        /// The role instance id.\n        /// </summary>\n        public string InstanceId { get; private set; }\n\n        /// <summary>\n        /// The location on the role instance where applications will be installed.\n        /// </summary>\n        public string ApplicationInstallDirectory { get; private set; }\n\n        /// <summary>\n        /// How frequently to check for updates (in seconds).\n        /// </summary>\n        public int CheckForUpdatesPeriodInSeconds { get; private set; }\n\n        /// <summary>\n        /// How many times should YAMS attempt to restart and application that fails.\n        /// </summary>\n        public int ApplicationRestartCount { get; private set; }\n\n        /// <summary>\n        /// How long should we wait after an application is stopped (to give it time to exit and free resources).\n        /// </summary>\n        public int ProcessWaitForExitInSeconds { get; private set; }\n\n        /// <summary>\n        /// Whether the process is started with UseShellExecute or not\n        /// </summary>\n        public bool UseShellExecute { get; private set; }\n\n        /// <summary>\n        /// How long Yams should wait for the app to receive the graceful exit message\n        /// </summary>\n        public TimeSpan GracefulShutdownMessageTimeout { get; private set; }\n\n        /// <summary>\n        /// How long the app is given to exit after receiving the exit message\n        /// </summary>\n        public TimeSpan AppGracefulShutdownTimeout { get; private set; }\n\n        /// <summary>\n        /// Apps that are subscribed to health check periodically send heart beats messages to Yams.\n        /// This property is the timeout after which Yams will declare the app unhealthy.\n        /// </summary>\n        public TimeSpan AppHeartBeatTimeout { get; private set; }\n\n        /// <summary>\n        /// Timeout for establishing an IPC connection with apps\n        /// </summary>\n        public TimeSpan IpcConnectTimeout { get; private set; }\n\n        /// <summary>\n        /// Time given to apps to finish initialization\n        /// </summary>\n        public TimeSpan AppInitTimeout { get; private set; }\n\n        /// <summary>\n        /// TTL after which an update session will be considered expired.\n        /// </summary>\n        public TimeSpan UpdateSessionTtl { get; }\n\n        public IReadOnlyDictionary<string, string> ClusterProperties { get; private set; }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/YamsConfigBuilder.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace Etg.Yams\n{\n    public class YamsConfigBuilder\n    {\n        public YamsConfigBuilder(string clusterId, string instanceUpdateDomain, \n            string instanceId, string applicationInstallDirectory)\n        {\n            _clusterId = clusterId;\n            _instanceUpdateDomain = instanceUpdateDomain;\n            _instanceId = instanceId;\n            _applicationInstallDirectory = applicationInstallDirectory;\n            _superClusterId = clusterId;\n            _checkForUpdatesPeriodInSeconds = 10;\n            _applicationRestartCount = 3;\n            _processWaitForExitInSeconds = 5;\n            _useShellExecute = true;\n            _gracefulShutdownMessageTimeout = TimeSpan.FromSeconds(30);\n            _appGracefulShutdownTimeout = TimeSpan.FromSeconds(60);\n            _appHeartBeatTimeout = TimeSpan.FromSeconds(60);\n            _ipcConnectTimeout = TimeSpan.FromSeconds(60);\n            _appInitTimeout = TimeSpan.FromSeconds(60);\n            _updateSessionTtl = TimeSpan.FromHours(1);\n        }\n\n        public YamsConfigBuilder SetSuperClusterId(string superClusterId)\n        {\n            if (superClusterId == null)\n                throw new ArgumentNullException(\n                    nameof(superClusterId), \n                    \"SuperClusterId cannot be null. If you don't need to use SuperCluster feature than you don't have to set this setting - SuperClusterId will defaut to CluserId\");\n\n            _superClusterId = superClusterId;\n            return this;\n        }\n\n        public YamsConfigBuilder SetCheckForUpdatesPeriodInSeconds(int value)\n        {\n            _checkForUpdatesPeriodInSeconds = value;\n            return this;\n        }\n\n        public YamsConfigBuilder SetApplicationRestartCount(int value)\n        {\n            _applicationRestartCount = value;\n            return this;\n        }\n\n        public YamsConfigBuilder SetProcessWaitForExitInSeconds(int value)\n        {\n            _processWaitForExitInSeconds = value;\n            return this;\n        }\n\n        [Obsolete(\"SetShowApplicationProcessWindow is obsolete, use SetUseShellExecute (which is equivalent)\")]\n        public YamsConfigBuilder SetShowApplicationProcessWindow(bool value)\n        {\n            _useShellExecute = value;\n            return this;\n        }\n\n        public YamsConfigBuilder SetUseShellExecute(bool value)\n        {\n            _useShellExecute = value;\n            return this;\n        }\n\n        public YamsConfigBuilder AddClusterProperty(string key, string value)\n        {\n            _clusterProperties[key] = value;\n            return this;\n        }\n\n        public YamsConfigBuilder SetGracefulShutdownMessageTimeout(TimeSpan timeout)\n        {\n            _gracefulShutdownMessageTimeout = timeout;\n            return this;\n        }\n\n        public YamsConfigBuilder SetAppGracefulShutdownTimeout(TimeSpan timeout)\n        {\n            _appGracefulShutdownTimeout = timeout;\n            return this;\n        }\n\n        public YamsConfigBuilder SetAppHeartBeatTimeout(TimeSpan timeout)\n        {\n            _appHeartBeatTimeout = timeout;\n            return this;\n        }\n\n        public YamsConfigBuilder SetIpcConnectTimeout(TimeSpan timeout)\n        {\n            _ipcConnectTimeout = timeout;\n            return this;\n        }\n\n        public YamsConfigBuilder SetAppInitTimeout(TimeSpan timeout)\n        {\n            _appInitTimeout = timeout;\n            return this;\n        }\n\n        public YamsConfigBuilder SetUpdateSessionTtl(TimeSpan ttl)\n        {\n            _updateSessionTtl = ttl;\n            return this;\n        }\n\n        public YamsConfig Build()\n        {\n            return new YamsConfig(\n                _superClusterId,\n                _clusterId,\n                _instanceUpdateDomain,\n                _instanceId,\n                _applicationInstallDirectory,\n                _checkForUpdatesPeriodInSeconds,\n                _applicationRestartCount,\n                _processWaitForExitInSeconds,\n                _useShellExecute,\n                _gracefulShutdownMessageTimeout,\n                _appGracefulShutdownTimeout,\n                _appHeartBeatTimeout,\n                _ipcConnectTimeout,\n                _appInitTimeout,\n                _updateSessionTtl,\n                _clusterProperties);\n        }\n\n        private readonly string _clusterId;\n        private readonly string _instanceUpdateDomain;\n        private readonly string _instanceId;\n        private readonly string _applicationInstallDirectory;\n        private string _superClusterId;\n        private int _checkForUpdatesPeriodInSeconds;\n        private int _applicationRestartCount;\n        private int _processWaitForExitInSeconds;\n        private bool _useShellExecute;\n        private TimeSpan _gracefulShutdownMessageTimeout;\n        private TimeSpan _appGracefulShutdownTimeout;\n        private TimeSpan _appHeartBeatTimeout;\n        private TimeSpan _ipcConnectTimeout;\n        private TimeSpan _appInitTimeout;\n        private readonly Dictionary<string, string> _clusterProperties = new Dictionary<string, string>();\n        private TimeSpan _updateSessionTtl;\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Core/YamsDiModule.cs",
    "content": "﻿using System.IO;\nusing Etg.Yams.Application;\nusing Etg.Yams.Deploy;\nusing Etg.Yams.Download;\nusing Etg.Yams.Process;\nusing Etg.Yams.Install;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Update;\nusing Etg.Yams.Watcher;\nusing Autofac;\nusing Etg.Yams.Json;\nusing Newtonsoft.Json.Serialization;\nusing Etg.Yams.Os;\n\nnamespace Etg.Yams\n{\n    /// <summary>\n    /// Class used for DI registration.\n    /// </summary>\n    public class YamsDiModule\n    {\n        private readonly IContainer _container;\n\n        public YamsDiModule(YamsConfig config, IDeploymentRepository deploymentRepository,\n            IDeploymentStatusWriter deploymentStatusWriter,\n            IUpdateSessionManager updateSessionManager)\n        {\n            _container = RegisterTypes(config, deploymentRepository, deploymentStatusWriter, \n                updateSessionManager).Build();\n        }\n\n        public YamsDiModule(IContainer container)\n        {\n            _container = container;\n        }\n\n        public IYamsService YamsService => _container.Resolve<IYamsService>();\n\n        public IContainer Container => _container;\n\n        public static ContainerBuilder RegisterTypes(YamsConfig config, \n            IDeploymentRepository deploymentRepository, IDeploymentStatusWriter deploymentStatusWriter,\n            IUpdateSessionManager updateSessionManager)\n        {\n            var builder = new ContainerBuilder();\n\n            RegisterConfig(builder, config);\n\n            RegisterProcessFactory(builder);\n\n            RegisterProcessStopper(builder);\n\n            RegisterApplicationConfigSymbolResolver(builder);\n\n            RegisterApplicationConfigParser(builder);\n\n            RegisterConfigurableApplicationFactory(builder);\n\n            RegisterApplicationDeploymentDirectory(builder);\n\n            RegisterApplicationPool(builder);\n\n            RegisterApplicationInstaller(builder);\n\n            RegisterApplicationDownloader(builder);\n\n            RegisterApplicationUpdateManager(builder);\n\n            RegisterDeploymentWatcher(builder);\n\n            builder.RegisterInstance(updateSessionManager);\n\n            builder.RegisterInstance(deploymentRepository);\n            builder.RegisterInstance(deploymentStatusWriter);\n\n            builder.RegisterType<YamsService>().As<IYamsService>().SingleInstance();\n\n            RegisterAppDeploymentMatcher(builder);\n\n            builder.RegisterType<DiagnosticsTraceWriter>().As<ITraceWriter>().SingleInstance();\n            builder.RegisterType<JsonSerializer>().As<IJsonSerializer>().SingleInstance();\n\n            builder.RegisterType<Os.System>().As<ISystem>().SingleInstance();\n\n            return builder;\n        }\n\n        private static void RegisterAppDeploymentMatcher(ContainerBuilder builder)\n        {\n            builder.Register<IAppDeploymentMatcher>(c =>\n            {\n                var config = c.Resolve<YamsConfig>();\n                var propertiesDeploymentMatcher = new PropertiesDeploymentMatcher(config.ClusterProperties);\n                var clusterIdDeploymentMatcher = new ClusterIdDeploymentMatcher(config.ClusterId);\n                return new AndDeploymentMatcher(clusterIdDeploymentMatcher, propertiesDeploymentMatcher);\n            });\n        }\n\n        private static void RegisterDeploymentWatcher(ContainerBuilder builder)\n        {\n            builder.Register<IDeploymentWatcher>(c =>\n            {\n                var config = c.Resolve<YamsConfig>();\n                return new DeploymentWatcher(c.Resolve<IApplicationUpdateManager>(),\n                    config.CheckForUpdatesPeriodInSeconds);\n            }).SingleInstance();\n        }\n\n        private static void RegisterApplicationUpdateManager(ContainerBuilder builder)\n        {\n            builder.Register<IApplicationUpdateManager>(\n                c =>\n                {\n                    var config = c.Resolve<YamsConfig>();\n                    return new ApplicationUpdateManager(config.ClusterId, config.InstanceId,\n                        c.Resolve<IApplicationDeploymentDirectory>(), c.Resolve<IApplicationPool>(),\n                        c.Resolve<IApplicationDownloader>(), c.Resolve<IApplicationInstaller>(),\n                        c.Resolve<IDeploymentStatusWriter>(), c.Resolve<IUpdateSessionManager>());\n                }).SingleInstance();\n        }\n\n        private static void RegisterConfigurableApplicationFactory(ContainerBuilder builder)\n        {\n            builder.Register<IApplicationFactory>(c => new ConfigurableApplicationFactory(\n                    c.Resolve<IApplicationConfigParser>(), c.Resolve<IProcessFactory>(), c.Resolve<IProcessStopper>())).SingleInstance();\n        }\n\n        private static void RegisterProcessStopper(ContainerBuilder builder)\n        {\n            builder.Register<IProcessStopper>(c =>\n            {\n                var config = c.Resolve<YamsConfig>();\n                return new ProcessStopper(config.ProcessWaitForExitInSeconds);\n            }).SingleInstance();\n        }\n\n        private static void RegisterApplicationConfigParser(ContainerBuilder builder)\n        {\n            builder.RegisterType<ApplicationConfigParser>().As<IApplicationConfigParser>().SingleInstance();\n        }\n\n        private static void RegisterApplicationConfigSymbolResolver(ContainerBuilder builder)\n        {\n            builder.Register<IApplicationConfigSymbolResolver>(c =>\n                {\n                    YamsConfig config = c.Resolve<YamsConfig>();\n                    return new ApplicationConfigSymbolResolver(config.ClusterId, config.InstanceId, config.ClusterProperties);\n                }).SingleInstance();\n        }\n\n        private static void RegisterApplicationPool(ContainerBuilder builder)\n        {\n            builder.Register<IApplicationPool>(c => new ApplicationPool()).SingleInstance();\n        }\n\n        private static void RegisterApplicationDownloader(ContainerBuilder builder)\n        {\n            builder.Register<IApplicationDownloader>(\n                c =>\n                {\n                    var config = c.Resolve<YamsConfig>();\n                    return new ApplicationDownloader(config.ApplicationInstallDirectory, c.Resolve<IDeploymentRepository>());\n                }).SingleInstance();\n        }\n\n        private static void RegisterApplicationInstaller(ContainerBuilder builder)\n        {\n            builder.Register<IApplicationInstaller>(\n                c =>\n                {\n                    var config = c.Resolve<YamsConfig>();\n                    return new ApplicationInstaller(Path.Combine(config.ApplicationInstallDirectory),\n                        c.Resolve<IApplicationFactory>(), c.Resolve<IApplicationPool>());\n                }).SingleInstance();\n        }\n\n        private static void RegisterProcessFactory(ContainerBuilder builder)\n        {\n            builder.Register<IProcessFactory>(c =>\n                {\n                    var config = c.Resolve<YamsConfig>();\n                    ISystem system = c.Resolve<ISystem>();\n                    return new ProcessFactory(config, system);\n                }).SingleInstance();\n        }\n\n        private static void RegisterConfig(ContainerBuilder builder, YamsConfig config)\n        {\n            builder.RegisterInstance(config);\n        }\n\n        private static void RegisterApplicationDeploymentDirectory(ContainerBuilder builder)\n        {\n            builder.Register<IApplicationDeploymentDirectory>(\n                c => new RemoteApplicationDeploymentDirectory(c.Resolve<IDeploymentRepository>(),\n                c.Resolve<IAppDeploymentMatcher>())).SingleInstance();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/YamsService.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Watcher;\nusing Autofac;\nusing System;\n\nnamespace Etg.Yams\n{\n    /// <summary>\n    /// The entry point class for YAMS. This class allows one to configure and start YAMS.\n    /// </summary>\n    public class YamsService : IYamsService, IDisposable\n    {\n        private readonly IDeploymentWatcher _deploymentWatcher;\n        private readonly IApplicationPool _applicationPool;\n\n        public YamsService(IDeploymentWatcher deploymentWatcher, IApplicationPool applicationPool) \n        {\n            _deploymentWatcher = deploymentWatcher;\n            _applicationPool = applicationPool;\n        }\n\n        public Task Start()\n        {\n            return _deploymentWatcher.Start();\n        }\n\n        public async Task Stop()\n        {\n            await _deploymentWatcher.Stop();\n            await _applicationPool.Shutdown();\n        }\n\n        public void Dispose()\n        {\n            Stop().Wait();\n            _applicationPool.Dispose();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Core/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net451\" />\n  <package id=\"System.Runtime\" version=\"4.1.0\" targetFramework=\"net451\" />\n  <package id=\"System.Runtime.Extensions\" version=\"4.1.0\" targetFramework=\"net451\" />\n  <package id=\"System.Runtime.InteropServices\" version=\"4.1.0\" targetFramework=\"net451\" />\n  <package id=\"System.Text.RegularExpressions\" version=\"4.1.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "src/Etg.Yams.Host/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.6.1\" />\n    </startup>\n</configuration>"
  },
  {
    "path": "src/Etg.Yams.Host/Etg.Yams.Host.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{C9A993F7-E3E2-4FDC-AA1E-01348B023D16}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <RootNamespace>Etg.Yams.Host</RootNamespace>\n    <AssemblyName>Etg.Yams.Host</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Etg.Yams.Core\\Etg.Yams.Core.csproj\">\n      <Project>{7145e485-34fa-4632-89b0-bd27c96af69c}</Project>\n      <Name>Etg.Yams.Core</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Etg.Yams\\Etg.Yams.csproj\">\n      <Project>{e1a6854f-6c0d-4f93-9b8d-d6981727d15b}</Project>\n      <Name>Etg.Yams</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n</Project>"
  },
  {
    "path": "src/Etg.Yams.Host/Program.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Host\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            Trace.Listeners.Add(new ConsoleTraceListener());\n            MainAsync(args).GetAwaiter().GetResult();\n        }\n\n        static async Task MainAsync(string[] args)\n        {\n            string clusterId = \"testClusterId\";\n            string superClusterId = \"testSuperClusterId\";\n\n            YamsConfig yamsConfig = new YamsConfigBuilder(\n                    // mandatory configs\n                    clusterId: clusterId,\n                    instanceUpdateDomain: \"0\",\n                    instanceId: \"instance_0\",\n                    applicationInstallDirectory: Directory.GetCurrentDirectory())\n                // optional configs\n                .SetSuperClusterId(superClusterId)\n                .SetCheckForUpdatesPeriodInSeconds(5)\n                .SetApplicationRestartCount(int.MaxValue)\n                .Build();\n\n            string storageConnectionString = \"UseDevelopmentStorage=true\";\n            var yamsService = YamsServiceFactory.Create(yamsConfig,\n                deploymentRepositoryStorageConnectionString: storageConnectionString,\n                updateSessionStorageConnectionString: storageConnectionString);\n\n            try\n            {\n                Trace.TraceInformation(\"Yams is starting\");\n                await yamsService.Start();\n                Trace.TraceInformation($\"Yams has started. Looking for apps with clusterId: {clusterId}\");\n            }\n            catch (Exception e)\n            {\n                Trace.TraceError($\"Failed to start the Yams cluster {clusterId}\", e);\n                return;\n            }\n\n            while (true)\n            {\n                await Task.Delay(1000);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Host/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Etg.Yams.Host\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Etg.Yams.Host\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2017\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible\n// to COM components.  If you need to access a type in this assembly from\n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"c9a993f7-e3e2-4fdc-aa1e-01348b023d16\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers\n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/Etg.Yams.Ipc/Etg.Yams.Ipc.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{C7C03D37-F2D2-4115-8423-86C1BF1B8A18}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Ipc</RootNamespace>\n    <AssemblyName>Etg.Yams.Ipc</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"IIpcConnection.cs\" />\n    <Compile Include=\"INamedPipe.cs\" />\n    <Compile Include=\"INamedPipeFactory.cs\" />\n    <Compile Include=\"IpcConnection.cs\" />\n    <Compile Include=\"NamedPipeClientAdapter.cs\" />\n    <Compile Include=\"NamedPipeFactory.cs\" />\n    <Compile Include=\"NamedPipeServerAdapter.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n</Project>"
  },
  {
    "path": "src/Etg.Yams.Ipc/IIpcConnection.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Ipc\n{\n    public interface IIpcConnection : IDisposable\n    {\n        Task SendMessage(string message);\n        Task<string> ReadMessage();\n        Task Connect();\n        Task Disconnect();\n        string ConnectionId { get; }\n        bool IsConnected { get; }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Ipc/INamedPipe.cs",
    "content": "﻿using System;\nusing System.IO;\n\nnamespace Etg.Yams.Ipc\n{\n    public interface INamedPipe : IDisposable\n    {\n        Stream Stream { get; }\n        bool IsConnected { get; }\n        string PipeName { get; }\n        void Connect();\n        void Disconnect();\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Ipc/INamedPipeFactory.cs",
    "content": "﻿namespace Etg.Yams.Ipc\n{\n    public interface INamedPipeFactory\n    {\n        INamedPipe CreateServer(string pipeName);\n        INamedPipe CreateClient(string pipeName);\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Ipc/IpcConnection.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.Ipc\n{\n    public class IpcConnection : IIpcConnection\n    {\n        private readonly INamedPipe _namedPipe;\n        private StreamWriter _streamWriter;\n        private StreamReader _streamReader;\n\n        public IpcConnection(INamedPipe namedPipe)\n        {\n            _namedPipe = namedPipe;\n        }\n\n        public async Task SendMessage(string message)\n        {\n            EnsureConnected();\n            await _streamWriter.WriteLineAsync(message);\n        }\n\n        public Task<string> ReadMessage()\n        {\n            EnsureConnected();\n            return _streamReader.ReadLineAsync();\n        }\n\n        public async Task Connect()\n        {\n            if(_namedPipe.IsConnected)\n            {\n                throw new InvalidOperationException($\"Named pipe {ConnectionId} is already connected\");\n            }\n            await Task.Run(() => _namedPipe.Connect());\n            _streamWriter = new StreamWriter(_namedPipe.Stream) {AutoFlush = true};\n            _streamReader = new StreamReader(_namedPipe.Stream);\n        }\n\n        public string ConnectionId => _namedPipe.PipeName;\n\n        public bool IsConnected => _namedPipe?.IsConnected?? false;\n\n        public void Dispose()\n        {\n            Disconnect().Wait();\n            _namedPipe.Dispose();\n        }\n\n        public Task Disconnect()\n        {\n            _streamWriter?.Dispose();\n            _streamWriter = null;\n            _streamReader?.Dispose();\n            _streamReader = null;\n            if (_namedPipe.IsConnected)\n            {\n                _namedPipe.Disconnect();\n            }\n            return Task.FromResult(true);\n        }\n\n        private void EnsureConnected()\n        {\n            if (!_namedPipe.IsConnected)\n            {\n                throw new InvalidOperationException(\"There is no valid IPC connection\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Ipc/NamedPipeClientAdapter.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.IO.Pipes;\n\nnamespace Etg.Yams.Ipc\n{\n    // This class is excluded from code coverage because it's being covered by E2E tests but the code coverage\n    // analyzer cannot see it because it's being run in a separate test process.\n    [ExcludeFromCodeCoverage]\n    public class NamedPipeClientAdapter : INamedPipe\n    {\n        private readonly NamedPipeClientStream _client;\n\n        public Stream Stream => _client;\n        public bool IsConnected => _client.IsConnected;\n        public string PipeName { get; }\n\n        public NamedPipeClientAdapter(string pipeName)\n        {\n            _client = new NamedPipeClientStream(\".\", pipeName, PipeDirection.InOut);\n            PipeName = pipeName;\n        }\n\n        public void Connect()\n        {\n            _client.Connect();\n        }\n\n        public void Disconnect()\n        {\n            if (_client.IsConnected)\n            {\n                _client.Close();\n            }\n        }\n\n        public void Dispose()\n        {\n            _client.Dispose();\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Ipc/NamedPipeFactory.cs",
    "content": "﻿namespace Etg.Yams.Ipc\n{\n    public class NamedPipeFactory : INamedPipeFactory\n    {\n        public INamedPipe CreateServer(string pipeName)\n        {\n            return new NamedPipeServerAdapter(pipeName);   \n        }\n\n        public INamedPipe CreateClient(string pipeName)\n        {\n            return new NamedPipeClientAdapter(pipeName);\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Ipc/NamedPipeServerAdapter.cs",
    "content": "﻿using System.IO;\nusing System.IO.Pipes;\n\nnamespace Etg.Yams.Ipc\n{\n    public class NamedPipeServerAdapter : INamedPipe\n    {\n        private readonly NamedPipeServerStream _server;\n\n        public NamedPipeServerAdapter(string pipeName)\n        {\n            _server = new NamedPipeServerStream(pipeName, PipeDirection.InOut);\n            PipeName = pipeName;\n        }\n\n        public Stream Stream => _server;\n        public bool IsConnected => _server.IsConnected;\n        public string PipeName { get; }\n\n        public void Connect()\n        {\n            _server.WaitForConnection();\n        }\n\n        public void Disconnect()\n        {\n            _server.Close();\n        }\n\n        public void Dispose()\n        {\n            _server.Dispose();\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Ipc/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Etg.Yams.Ipc\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Etg.Yams.Ipc\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2017\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible\n// to COM components.  If you need to access a type in this assembly from\n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"c7c03d37-f2d2-4115-8423-86c1bf1b8a18\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers\n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/Etg.Yams.Powershell/ConnectDeploymentRepositoryCmdlet.cs",
    "content": "﻿using Etg.Yams.Azure.Storage;\nusing Etg.Yams.Storage;\nusing System;\nusing System.Management.Automation;\n\nnamespace Etg.Yams.Powershell\n{\n    [Cmdlet(VerbsCommunications.Connect, \"DeploymentRepository\")]\n    [OutputType(typeof(IDeploymentRepository))]\n\n    public class ConnectDeploymentRepositoryCmdlet : Cmdlet\n    {\n        [Parameter]\n        public string ConnectionString { get; set; }\n\n        protected override void ProcessRecord()\n        {\n            if (string.IsNullOrWhiteSpace(ConnectionString))\n            {\n                throw new ArgumentException(nameof(ConnectionString));\n            }\n            var deploymentRepository = BlobStorageDeploymentRepository.Create(ConnectionString);\n            WriteObject(deploymentRepository);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Powershell/Etg.Yams.Powershell.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{CDFBE3EE-AFD7-467F-BE9C-F9EAFC7A05CE}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Powershell</RootNamespace>\n    <AssemblyName>Etg.Yams.Powershell</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Microsoft.PowerShell.5.ReferenceAssemblies.1.1.0\\lib\\net4\\System.Management.Automation.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"ConnectDeploymentRepositoryCmdlet.cs\" />\n    <Compile Include=\"GetDeploymentConfigCmdlet.cs\" />\n    <Compile Include=\"GetDeploymentStatusCmdlet.cs\" />\n    <Compile Include=\"InstallApplicationsCmdlet.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"SetDeploymentConfigCmdlet.cs\" />\n    <Compile Include=\"UninstallApplicationsCmdlet.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\AzureBlobStorageDeploymentRepository\\AzureBlobStorageDeploymentRepository.csproj\">\n      <Project>{df95a9dc-f6be-4c71-b444-4092b43eb602}</Project>\n      <Name>AzureBlobStorageDeploymentRepository</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Common\\Common.csproj\">\n      <Project>{3e982150-5b43-44da-8d96-66cf07a9a14c}</Project>\n      <Name>Common</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Etg.Yams.Core\\Etg.Yams.Core.csproj\">\n      <Project>{7145e485-34fa-4632-89b0-bd27c96af69c}</Project>\n      <Name>Etg.Yams.Core</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n</Project>"
  },
  {
    "path": "src/Etg.Yams.Powershell/Etg.Yams.Powershell.nuspec",
    "content": "<?xml version=\"1.0\"?>\n<package >\n  <metadata>\n    <id>Etg.Yams.Powershell</id>\n    <version>1.2.1</version>\n    <title>YAMS Powershell</title>\n    <authors>Nehme Bilal</authors>\n    <owners>Microsoft Studios (BigPark)</owners>\n    <licenseUrl>https://opensource.org/licenses/MIT</licenseUrl>\n\t<projectUrl>https://github.com/Microsoft/Yams</projectUrl>\n    <requireLicenseAcceptance>false</requireLicenseAcceptance>\n    <description>Exposes several Powershell cmdlets that can be used to manage YAMS clusters.</description>\n    <copyright>Copyright (c) Microsoft Corporation</copyright>\n  </metadata>\n    <files>\n    <file src=\"bin\\$configuration$\\**\" target=\"content\" />\n  </files>\n</package>"
  },
  {
    "path": "src/Etg.Yams.Powershell/GetDeploymentConfigCmdlet.cs",
    "content": "﻿using System;\nusing System.Management.Automation;\nusing Etg.Yams.Azure.Storage;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Powershell\n{\n    [Cmdlet(VerbsCommon.Get, \"DeploymentConfig\")]\n    [OutputType(typeof(DeploymentConfig))]\n    public class GetDeploymentConfigCmdlet : Cmdlet\n    {\n        [Parameter(Mandatory = true, HelpMessage = \"The connection string of the Yams storage\")]\n        public string ConnectionString { get; set; }\n\n        protected override void ProcessRecord()\n        {\n            try\n            {\n                if (string.IsNullOrWhiteSpace(ConnectionString))\n                {\n                    throw new ArgumentException(nameof(ConnectionString));\n                }\n\n                int activityId = 0;\n                var progressRecord = new ProgressRecord(activityId++, \"Connect to blob storage\",\n                    \"Connecting to blob storage\");\n                WriteProgress(progressRecord);\n                var deploymentRepository = BlobStorageDeploymentRepository.Create(ConnectionString);\n                progressRecord.RecordType = ProgressRecordType.Completed;\n                WriteProgress(progressRecord);\n\n                progressRecord = new ProgressRecord(activityId++, \"FetchDeploymentConfig\",\n                    \"Fetching DeploymentConfig.json from blob storage\");\n                WriteProgress(progressRecord);\n                var deploymentConfig = deploymentRepository.FetchDeploymentConfig().Result;\n                progressRecord.RecordType = ProgressRecordType.Completed;\n                WriteProgress(progressRecord);\n\n                WriteObject(deploymentConfig);\n            }\n            catch (Exception e)\n            {\n                ThrowTerminatingError(new ErrorRecord(e, \"0\", ErrorCategory.OperationStopped, null));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Powershell/GetDeploymentStatusCmdlet.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Management.Automation;\nusing Etg.Yams.Azure.Storage;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Storage.Status;\n\nnamespace Etg.Yams.Powershell\n{\n    [Cmdlet(VerbsCommon.Get, \"DeploymentStatus\")]\n    [OutputType(typeof(DeploymentConfig))]\n    public class GetDeploymentStatusCmdlet : Cmdlet\n    {\n        [Parameter(Mandatory = true, HelpMessage = \"The connection string of the Yams storage\")]\n        public string ConnectionString { get; set; }\n\n        [Parameter(Mandatory = false, HelpMessage = \"The id of the cluster\")]\n        public string ClusterId { get; set; }\n\n        [Parameter(Mandatory = false, \n            HelpMessage = \"Allow one to only show app that have been active within the last ActiveSince seconds. \" +\n            \"Default is 5 minutes\")]\n        public int ActiveSince { get; set; } = int.MaxValue;\n\n        protected override void ProcessRecord()\n        {\n            if (string.IsNullOrWhiteSpace(ConnectionString))\n            {\n                throw new ArgumentException(nameof(ConnectionString));\n            }\n\n            int activityId = 0;\n            var progressRecord = new ProgressRecord(activityId++, \"Connect to blob storage\",\n                \"Connecting to blob storage\");\n            WriteProgress(progressRecord);\n            var deploymentRepository = BlobStorageDeploymentRepository.Create(ConnectionString);\n            progressRecord.RecordType = ProgressRecordType.Completed;\n            WriteProgress(progressRecord);\n\n            progressRecord = new ProgressRecord(activityId++, \"FetchDeploymentConfig\", \"Fetching DeploymentConfig from storage\");\n            WriteProgress(progressRecord);\n            var deploymentConfig = deploymentRepository.FetchDeploymentConfig().Result;\n            progressRecord.RecordType = ProgressRecordType.Completed;\n            WriteProgress(progressRecord);\n\n            progressRecord = new ProgressRecord(activityId++, \"FetchDeploymentStatus\", $\"Fetching DeploymentStatus\");\n            WriteProgress(progressRecord);\n            var deploymentStatus = GetDeploymentStatus(deploymentRepository);\n            progressRecord.RecordType = ProgressRecordType.Completed;\n            WriteProgress(progressRecord);\n\n            WriteObject(deploymentStatus);\n        }\n\n        private DeploymentStatus GetDeploymentStatus(BlobStorageDeploymentRepository deploymentRepository)\n        {\n            if (string.IsNullOrWhiteSpace(ClusterId))\n            {\n                return GetAllClustersDeploymentStatus(deploymentRepository);\n            }\n            return GetClusterDeploymentStatus(deploymentRepository, ClusterId);\n        }\n\n        private DeploymentStatus GetClusterDeploymentStatus(BlobStorageDeploymentRepository deploymentRepository, \n            string clusterId)\n        {\n            var apps = deploymentRepository.FetchClusterDeploymentStatus(clusterId, ttlSeconds: ActiveSince).Result;\n            return new DeploymentStatus(apps);\n        }\n\n        private DeploymentStatus GetAllClustersDeploymentStatus(BlobStorageDeploymentRepository deploymentRepository)\n        {\n            var deploymentConfig = deploymentRepository.FetchDeploymentConfig().Result;\n            IEnumerable<string> clustersIds = deploymentConfig.ListClusters();\n            var apps = new List<AppDeploymentStatus>();\n\n            foreach (string clusterId in clustersIds)\n            {\n                var clusterStatus = deploymentRepository.FetchClusterDeploymentStatus(clusterId, ttlSeconds: ActiveSince).Result;\n                apps.AddRange(clusterStatus.ListAll());\n            }\n            return new DeploymentStatus(apps);\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Powershell/InstallApplicationsCmdlet.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Management.Automation;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Azure.Storage;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Storage.Status;\nusing Newtonsoft.Json;\n\nnamespace Etg.Yams.Powershell\n{\n\n    [Cmdlet(VerbsLifecycle.Install, \"Applications\")]\n    [OutputType(typeof(DeploymentConfig))]\n    public class InstallApplicationsCmdlet : Cmdlet\n    {\n        [Parameter(Mandatory = true, HelpMessage = \"The connection string of the Yams storage\")]\n        public string ConnectionString { get; set; }\n\n        [Parameter(Mandatory = true, HelpMessage = \"The ids of the apps to publish\")]\n        public string[] AppsIds { get; set; }\n\n        [Parameter(Mandatory = true, \n            HelpMessage = \"The ids of the clusters; Entries order should correspond to entries in AppsIds\")]\n        public string[] ClustersIds { get; set; }\n\n        [Parameter(Mandatory = true, HelpMessage = \"The new versions to publish\" +\n                                                   \"Entries order should correspond to entries in AppsIds\")]\n        public string[] Versions { get; set; }\n\n        [Parameter(HelpMessage = \"The paths where binaries are located\" +\n                                                   \"Entries order should correspond to entries in AppsIds\")]\n        public string[] BinariesPath { get; set; }\n\n        [Parameter(HelpMessage = \"Waits until the deployment status has been updated, \" +\n                                 \"which indicates that the corresponding apps have been started\")]\n        public SwitchParameter WaitForDeploymentsToComplete { get; set; }\n\n        [Parameter(HelpMessage = \"Defines the behaviour when the binaries to upload already exist.\" +\n                                 \"The Default behaviour is to do nothing\")]\n        public ConflictResolutionMode BinariesConflictResolutionMode { get; set; } = ConflictResolutionMode.DoNothingIfBinariesExist;\n\n        [Parameter(HelpMessage = \"Indicates whether the DeploymentConfig.json should be uploaded\" +\n                                 \"which will trigger deployment\")]\n        public SwitchParameter Deploy { get; set; } = true;\n\n        [Parameter(HelpMessage = \"Remove previously deployed version(s) of the app (Defaults to 'true')\")]\n        public SwitchParameter RemoveOldVersions { get; set; } = true;\n\n        [Parameter(HelpMessage = \"The properties of the clusters; Entries order should correspond to entries in AppsIds. \" +\n            \"Example: {\\\"app1Prop1key\\\":\\\"app1Prop1Value\\\", \\\"app1Prop2Key\\\":\\\"app1Prop2Value\\\"}, {\\\"app2Prop1key\\\":\\\"app2Prop1Value\\\"}.\")]\n        public string[] Properties { get; set; }\n\n        protected override void ProcessRecord()\n        {\n            try\n            {\n                if (string.IsNullOrWhiteSpace(ConnectionString))\n                {\n                    throw new ArgumentException(nameof(ConnectionString));\n                }\n                if (ClustersIds?.Length != AppsIds.Length)\n                {\n                    throw new ArgumentException(nameof(ClustersIds));\n                }\n                if (Versions?.Length != AppsIds.Length)\n                {\n                    throw new ArgumentException(nameof(Versions));\n                }\n                if (BinariesPath?.Length != AppsIds.Length)\n                {\n                    throw new ArgumentException(nameof(BinariesPath));\n                }\n                if (AppsIds?.Length == 0)\n                {\n                    throw new ArgumentException(nameof(AppsIds));\n                }\n\n                int activityId = 0;\n                var progressRecord = new ProgressRecord(activityId++, \"Connect to blob storage\",\n                    \"Connecting to blob storage\");\n                WriteProgress(progressRecord);\n                var deploymentRepository = BlobStorageDeploymentRepository.Create(ConnectionString);\n                progressRecord.RecordType = ProgressRecordType.Completed;\n                WriteProgress(progressRecord);\n\n                if (BinariesPath != null)\n                {\n                    var tasks = new List<Task>();\n                    for (int i = 0; i < AppsIds.Length; ++i)\n                    {\n                        string appId = AppsIds[i];\n                        string version = Versions[i];\n                        string binariesPath = BinariesPath[i];\n\n                        var newAppIdentity = new AppIdentity(appId, version);\n\n                        if (BinariesPath != null)\n                        {\n                            tasks.Add(deploymentRepository.UploadApplicationBinaries(newAppIdentity, binariesPath,\n                                BinariesConflictResolutionMode));\n                        }\n                    }\n                    progressRecord = new ProgressRecord(activityId++, \"UploadApplicationBinaries\",\n                        \"Uploading binaries to blob storage\");\n                    WriteProgress(progressRecord);\n                    Task.WhenAll(tasks).Wait();\n                    progressRecord.RecordType = ProgressRecordType.Completed;\n                    WriteProgress(progressRecord);\n                }\n\n                if (Deploy)\n                {\n                    progressRecord = new ProgressRecord(activityId++, \"FetchDeploymentConfig\",\n                        \"Fetching DeploymentConfig.json from blob storage\");\n                    WriteProgress(progressRecord);\n                    var deploymentConfig = deploymentRepository.FetchDeploymentConfig().Result;\n                    progressRecord.RecordType = ProgressRecordType.Completed;\n                    WriteProgress(progressRecord);\n\n                    for (int i = 0; i < AppsIds.Length; ++i)\n                    {\n                        string appId = AppsIds[i];\n                        string version = Versions[i];\n                        string clusterId = ClustersIds[i];\n\n                        if (RemoveOldVersions && deploymentConfig.HasApplication(appId))\n                        {\n                            deploymentConfig = deploymentConfig.RemoveApplication(appId, clusterId);\n                        }\n\n                        var newAppIdentity = new AppIdentity(appId, version);\n\n                        if (!deploymentConfig.HasApplication(newAppIdentity, clusterId))\n                        {\n                            var appDeploymentConfig = deploymentConfig.HasApplication(newAppIdentity)? deploymentConfig.GetApplicationConfig(newAppIdentity) : new AppDeploymentConfig(newAppIdentity);\n                            appDeploymentConfig = appDeploymentConfig.AddClusterId(clusterId);\n                            if (Properties?.Length > i)\n                            {\n                                var appProperties = JsonConvert.DeserializeObject<Dictionary<string, string>>(Properties[i]);\n                                foreach (var kvp in appProperties)\n                                {\n                                    appDeploymentConfig = appDeploymentConfig.AddProperty(kvp.Key, kvp.Value);\n                                }\n                            }\n\n                            deploymentConfig = deploymentConfig.SetApplicationConfig(appDeploymentConfig);\n                        }\n                    }\n\n                    progressRecord = new ProgressRecord(activityId++, \"PublishDeploymentConfig\",\n                        \"Publishing DeploymentConfig.json to blob storage\");\n                    WriteProgress(progressRecord);\n                    deploymentRepository.PublishDeploymentConfig(deploymentConfig).Wait();\n                    progressRecord.RecordType = ProgressRecordType.Completed;\n                    WriteProgress(progressRecord);\n\n                    WriteObject(deploymentConfig);\n                }\n\n                if (WaitForDeploymentsToComplete)\n                {\n                    var waitForDeploymentsProgressRecord = new ProgressRecord(activityId++,\n                        \"WaitForDeploymentsToComplete\",\n                        \"Waiting for all deployments to complete\");\n                    WriteProgress(waitForDeploymentsProgressRecord);\n\n                    List<AppInfo> pendingApps = new List<AppInfo>();\n                    for (int i = 0; i < AppsIds.Length; ++i)\n                    {\n                        AppInfo app = new AppInfo\n                        {\n                            Id = AppsIds[i],\n                            Version = Versions[i],\n                            ClusterId = ClustersIds[i]\n                        };\n                        pendingApps.Add(app);\n                    }\n\n                    while (pendingApps.Any())\n                    {\n                        var appDeployments = new List<AppDeploymentStatus>();\n                        var fetchTasks = new List<Task<ClusterDeploymentStatus>>();\n\n                        progressRecord = new ProgressRecord(activityId++, \"FetchClusterDeploymentStatus\",\n                            \"Fetching deployments status\");\n                        WriteProgress(progressRecord);\n                        foreach (string clusterId in ClustersIds)\n                        {\n                            fetchTasks.Add(\n                                deploymentRepository.FetchClusterDeploymentStatus(clusterId, ttlSeconds: 60));\n                        }\n                        progressRecord.RecordType = ProgressRecordType.Completed;\n                        WriteProgress(progressRecord);\n\n                        ClusterDeploymentStatus[] result = Task.WhenAll(fetchTasks).Result;\n                        foreach (var clusterDeploymentStatus in result)\n                        {\n                            appDeployments.AddRange(clusterDeploymentStatus.ListAll());\n                        }\n\n                        foreach (var appDeploymentStatus in appDeployments)\n                        {\n                            AppInfo app = pendingApps.FirstOrDefault(\n                                appInfo => appInfo.ClusterId == appDeploymentStatus.ClusterId &&\n                                           appInfo.Id == appDeploymentStatus.Id &&\n                                           appInfo.Version == appDeploymentStatus.Version);\n                            if (app != null)\n                            {\n                                pendingApps.Remove(app);\n                                float quotient = (float) (AppsIds.Length - pendingApps.Count) / AppsIds.Length;\n                                waitForDeploymentsProgressRecord.PercentComplete = (int) (100 * quotient);\n                                WriteProgress(waitForDeploymentsProgressRecord);\n                            }\n                        }\n                        Task.Delay(TimeSpan.FromSeconds(1)).Wait();\n                    }\n\n                    waitForDeploymentsProgressRecord.RecordType = ProgressRecordType.Completed;\n                    WriteProgress(waitForDeploymentsProgressRecord);\n                }\n            }\n            catch (ArgumentException argException)\n            {\n                ThrowTerminatingError(new ErrorRecord(argException, \"0\", ErrorCategory.InvalidArgument, null));\n            }\n            catch (Exception e)\n            {\n                ThrowTerminatingError(new ErrorRecord(e, \"0\", ErrorCategory.OperationStopped, null));\n            }\n        }\n\n        private class AppInfo\n        {\n            public string Id;\n            public string Version;\n            public string ClusterId;\n        }\n    }\n}"
  },
  {
    "path": "src/Etg.Yams.Powershell/NuGetPack.bat",
    "content": "nuget pack Etg.Yams.Powershell.csproj -Prop Configuration=Release"
  },
  {
    "path": "src/Etg.Yams.Powershell/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Etg.Yams.Powershell\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Etg.Yams.Powershell\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2017\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible\n// to COM components.  If you need to access a type in this assembly from\n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"cdfbe3ee-afd7-467f-be9c-f9eafc7a05ce\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers\n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "src/Etg.Yams.Powershell/SetDeploymentConfigCmdlet.cs",
    "content": "﻿using System;\nusing System.Management.Automation;\nusing Etg.Yams.Azure.Storage;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Powershell\n{\n    [Cmdlet(VerbsCommon.Set, \"DeploymentConfig\")]\n    [OutputType(typeof(DeploymentConfig))]\n    public class SetDeploymentConfigCmdlet : Cmdlet\n    {\n        [Parameter(Mandatory = true, HelpMessage = \"The connection string of the Yams storage\")]\n        public string ConnectionString { get; set; }\n\n        [Parameter(Mandatory = true, HelpMessage = \"The deployment configuration to set\")]\n        public DeploymentConfig Config { get; set; }\n\n        protected override void ProcessRecord()\n        {\n            try\n            {\n                if (string.IsNullOrWhiteSpace(ConnectionString))\n                {\n                    throw new ArgumentException(nameof(ConnectionString));\n                }\n\n                int activityId = 0;\n                var progressRecord = new ProgressRecord(activityId++, \"Connect to blob storage\",\n                    \"Connecting to blob storage\");\n                WriteProgress(progressRecord);\n                var deploymentRepository = BlobStorageDeploymentRepository.Create(ConnectionString);\n                progressRecord.RecordType = ProgressRecordType.Completed;\n                WriteProgress(progressRecord);\n\n                progressRecord = new ProgressRecord(activityId++, \"PublishDeploymentConfig\",\n                    \"Publishing DeploymentConfig.json to blob storage\");\n                deploymentRepository.PublishDeploymentConfig(Config).Wait();\n                WriteProgress(progressRecord);\n\n                WriteObject(Config);\n            }\n            catch (Exception e)\n            {\n                ThrowTerminatingError(new ErrorRecord(e, \"0\", ErrorCategory.OperationStopped, null));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Powershell/UninstallApplicationsCmdlet.cs",
    "content": "﻿using System;\nusing System.Management.Automation;\nusing Etg.Yams.Application;\nusing Etg.Yams.Azure.Storage;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Powershell\n{\n    [Cmdlet(VerbsLifecycle.Uninstall, \"Applications\")]\n    [OutputType(typeof(DeploymentConfig))]\n    public class UninstallApplicationsCmdlet : Cmdlet\n    {\n        [Parameter(Mandatory = true, HelpMessage = \"The connection string of the Yams storage\")]\n        public string ConnectionString { get; set; }\n\n        [Parameter(Mandatory = true, HelpMessage = \"The ids of the apps to uninstall\")]\n        public string[] AppsIds { get; set; }\n\n        [Parameter(Mandatory = true,\n            HelpMessage = \"The ids of the clusters; Entries order should correspond to entries in AppsIds\")]\n        public string[] ClustersIds { get; set; }\n\n        [Parameter(Mandatory = true, HelpMessage = \"The versions to uninstall. \" +\n                                                   \"Entries order should correspond to entries in AppsIds\")]\n        public string[] Versions { get; set; }\n\n        protected override void ProcessRecord()\n        {\n            try\n            {\n                if (string.IsNullOrWhiteSpace(ConnectionString))\n                {\n                    throw new ArgumentException(nameof(ConnectionString));\n                }\n                if (ClustersIds.Length != AppsIds.Length)\n                {\n                    throw new ArgumentException(nameof(ClustersIds));\n                }\n                if (Versions.Length != AppsIds.Length)\n                {\n                    throw new ArgumentException(nameof(Versions));\n                }\n                if (AppsIds.Length == 0)\n                {\n                    throw new ArgumentException(nameof(AppsIds));\n                }\n\n                int activityId = 0;\n                var progressRecord = new ProgressRecord(activityId++, \"Connect to blob storage\",\n                    \"Connecting to blob storage\");\n                WriteProgress(progressRecord);\n                var deploymentRepository = BlobStorageDeploymentRepository.Create(ConnectionString);\n                progressRecord.RecordType = ProgressRecordType.Completed;\n                WriteProgress(progressRecord);\n\n                progressRecord = new ProgressRecord(activityId++, \"FetchDeploymentConfig\",\n                    \"Fetching DeploymentConfig.json from blob storage\");\n                WriteProgress(progressRecord);\n                var deploymentConfig = deploymentRepository.FetchDeploymentConfig().Result;\n                progressRecord.RecordType = ProgressRecordType.Completed;\n                WriteProgress(progressRecord);\n\n                for (int i = 0; i < AppsIds.Length; ++i)\n                {\n                    string appId = AppsIds[i];\n                    string version = Versions[i];\n                    string clusterId = ClustersIds[i];\n\n                    var toRemove = new AppIdentity(appId, version);\n                    if (deploymentConfig.HasApplication(toRemove))\n                    {\n                        deploymentConfig = deploymentConfig.RemoveApplication(toRemove);\n                    }\n                }\n\n                progressRecord = new ProgressRecord(activityId++, \"PublishDeploymentConfig\",\n                    \"Publishing DeploymentConfig.json to blob storage\");\n                WriteProgress(progressRecord);\n                deploymentRepository.PublishDeploymentConfig(deploymentConfig).Wait();\n                progressRecord.RecordType = ProgressRecordType.Completed;\n                WriteProgress(progressRecord);\n\n                WriteObject(deploymentConfig);\n            }\n            catch (Exception e)\n            {\n                ThrowTerminatingError(new ErrorRecord(e, \"0\", ErrorCategory.OperationStopped, null));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Etg.Yams.Powershell/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Newtonsoft.Json\" publicKeyToken=\"30ad4fe6b2a6aeed\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-10.0.0.0\" newVersion=\"10.0.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>"
  },
  {
    "path": "src/Etg.Yams.Powershell/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.PowerShell.5.ReferenceAssemblies\" version=\"1.1.0\" targetFramework=\"net461\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net461\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net461\" />\n</packages>"
  },
  {
    "path": "test/AzureBlobStorageDeploymentRepositoryTest/AzureBlobStorageDeploymentRepositoryTest.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{E66F281C-BD50-45B0-AAEF-FB87E4C9D0CC}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Azure.Storage.Test</RootNamespace>\n    <AssemblyName>AzureBlobStorageDeploymentRepositoryTest</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n    <VisualStudioVersion Condition=\"'$(VisualStudioVersion)' == ''\">10.0</VisualStudioVersion>\n    <VSToolsPath Condition=\"'$(VSToolsPath)' == ''\">$(MSBuildExtensionsPath32)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)</VSToolsPath>\n    <ReferencePath>$(ProgramFiles)\\Common Files\\microsoft shared\\VSTT\\$(VisualStudioVersion)\\UITestExtensionPackages</ReferencePath>\n    <IsCodedUITest>False</IsCodedUITest>\n    <TestProjectType>UnitTest</TestProjectType>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.abstractions.2.0.0\\lib\\net35\\xunit.abstractions.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.assert, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.assert.2.1.0\\lib\\dotnet\\xunit.assert.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.core, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.core.2.1.0\\lib\\dotnet\\xunit.core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.execution.desktop, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.execution.2.1.0\\lib\\net45\\xunit.execution.desktop.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n  </ItemGroup>\n  <Choose>\n    <When Condition=\"('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'\">\n      <ItemGroup>\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\" />\n      </ItemGroup>\n    </When>\n    <Otherwise>\n      <ItemGroup>\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.UnitTestFramework\" />\n      </ItemGroup>\n    </Otherwise>\n  </Choose>\n  <ItemGroup>\n    <Compile Include=\"BlobStorageDeploymentRepositoryTest.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\AzureBlobStorageDeploymentRepository\\AzureBlobStorageDeploymentRepository.csproj\">\n      <Project>{df95a9dc-f6be-4c71-b444-4092b43eb602}</Project>\n      <Name>AzureBlobStorageDeploymentRepository</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\AzureUtils\\AzureUtils.csproj\">\n      <Project>{1c890e49-5a9b-4eab-9f69-6a6e78d82610}</Project>\n      <Name>AzureUtils</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Common\\Common.csproj\">\n      <Project>{3e982150-5b43-44da-8d96-66cf07a9a14c}</Project>\n      <Name>Common</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Core\\Etg.Yams.Core.csproj\">\n      <Project>{7145e485-34fa-4632-89b0-bd27c96af69c}</Project>\n      <Name>Etg.Yams.Core</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\AzureTestUtils\\AzureTestUtils.csproj\">\n      <Project>{84c08621-2c78-4b19-9454-7b9019e68326}</Project>\n      <Name>AzureTestUtils</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"Data\\DeploymentRepository\\DeploymentConfig.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Choose>\n    <When Condition=\"'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'\">\n      <ItemGroup>\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n      </ItemGroup>\n    </When>\n  </Choose>\n  <Import Project=\"$(VSToolsPath)\\TeamTest\\Microsoft.TestTools.targets\" Condition=\"Exists('$(VSToolsPath)\\TeamTest\\Microsoft.TestTools.targets')\" />\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/AzureBlobStorageDeploymentRepositoryTest/BlobStorageDeploymentRepositoryTest.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Azure.Utils;\nusing Etg.Yams.AzureTestUtils.Fixtures;\nusing Etg.Yams.Json;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Utils;\nusing Microsoft.WindowsAzure.Storage.Blob;\nusing Newtonsoft.Json.Serialization;\nusing Semver;\nusing Xunit;\nusing Etg.Yams.Storage.Status;\n\nnamespace Etg.Yams.Azure.Storage.Test\n{\n    [Trait(\"Category\", \"Integration\")]\n    public class BlobStorageDeploymentRepositoryTest : IClassFixture<AzureStorageEmulatorTestFixture>\n    {\n        private const string EmulatorDataConnectionString = \"UseDevelopmentStorage=true\";\n        private const string TestAppFileName = \"AppConfig.json\";\n        private const string TestAppBlobRelPath = \"app/1.0.0\";\n        private const string TestAppId = \"app\";\n        private const string TestAppVersion = \"1.0.0\";\n        private static readonly AppIdentity TestAppIdentity = new AppIdentity(TestAppId, SemVersion.Parse(TestAppVersion));\n\n        private readonly string _deploymentConfigFilePath = Path.Combine(\"Data\", \"DeploymentRepository\",\n            \"DeploymentConfig.json\");\n\n        private static CloudBlobClient _blobClient;\n        private static BlobStorageDeploymentRepository _deploymentRepository;\n        private readonly IDeploymentConfigSerializer _serializer;\n        private readonly IDeploymentStatusSerializer _deploymentStatusSerializer;\n\n        public BlobStorageDeploymentRepositoryTest(AzureStorageEmulatorTestFixture fixture)\n        {\n            fixture.ClearBlobStorage();\n            _blobClient = fixture.BlobClient;\n\n            JsonSerializer jsonSerializer = new JsonSerializer(new DiagnosticsTraceWriter());\n            _serializer = new JsonDeploymentConfigSerializer(jsonSerializer);\n            _deploymentStatusSerializer = new JsonDeploymentStatusSerializer(jsonSerializer);\n            _deploymentRepository = new BlobStorageDeploymentRepository(EmulatorDataConnectionString, _serializer, \n                _deploymentStatusSerializer);\n        }\n\n        [Fact]\n        public async Task TestGetDeploymentConfigWhenTheFileIsNotThere()\n        {\n            DeploymentConfig deploymentConfig = await _deploymentRepository.FetchDeploymentConfig();\n            Assert.False(deploymentConfig.ListApplications().Any());\n        }\n\n        [Fact]\n        public async Task TestPublishThenFetchDeploymentConfig()\n        {\n            string data = File.ReadAllText(_deploymentConfigFilePath);\n            DeploymentConfig deploymentConfig = _serializer.Deserialize(data);\n            await _deploymentRepository.PublishDeploymentConfig(deploymentConfig);\n            DeploymentConfig newDeploymentConfig = await _deploymentRepository.FetchDeploymentConfig();\n            Assert.Equal(_serializer.Serialize(deploymentConfig), _serializer.Serialize(newDeploymentConfig));\n        }\n\n        [Fact]\n        public async Task TestUploadApplicationBinaries()\n        {\n            const string someJsonContent = \"some json content\";\n            await UploadTestApplicationBinaries(ConflictResolutionMode.FailIfBinariesExist, someJsonContent);\n            await VerifyBlobStorageContent(someJsonContent);\n        }\n\n        [Fact]\n        public async Task TestUploadApplicationBinaries_FailIfBinariesExistMode()\n        {\n            await Assert.ThrowsAsync<DuplicateBinariesException>(async () =>\n            {\n                const string originalJsonContent = \"some json content\";\n                await UploadTestApplicationBinaries(ConflictResolutionMode.FailIfBinariesExist, originalJsonContent);\n                await UploadTestApplicationBinaries(ConflictResolutionMode.FailIfBinariesExist, \"different content\");\n                await VerifyBlobStorageContent(originalJsonContent);\n\n            });\n        }\n\n        [Fact]\n        public async Task TestUploadApplicationBinaries_DoNothingBinariesExistMode()\n        {\n            const string originalJsonContent = \"some json content\";\n            await UploadTestApplicationBinaries(ConflictResolutionMode.FailIfBinariesExist, originalJsonContent);\n            await UploadTestApplicationBinaries(ConflictResolutionMode.DoNothingIfBinariesExist, \"different content\");\n            await VerifyBlobStorageContent(originalJsonContent);\n        }\n\n        [Fact]\n        public async Task TestUploadApplicationBinaries_OverwriteExistingBinariesMode()\n        {\n            const string originalJsonContent = \"some json content\";\n            await UploadTestApplicationBinaries(ConflictResolutionMode.FailIfBinariesExist, originalJsonContent);\n            const string newContent = \"different content\";\n            await UploadTestApplicationBinaries(ConflictResolutionMode.OverwriteExistingBinaries, newContent);\n            await VerifyBlobStorageContent(newContent);\n        }\n\n        [Fact]\n        public async Task TestUploadApplicationBinaries_EmptyBinariesDir()\n        {\n            const string testName = nameof(TestUploadApplicationBinaries_EmptyBinariesDir);\n            await Assert.ThrowsAsync<BinariesNotFoundException>(async () =>\n            {\n                string localPath = await CreateTestTempDirectory(testName);\n                await _deploymentRepository.UploadApplicationBinaries(TestAppIdentity, localPath, ConflictResolutionMode.OverwriteExistingBinaries);\n            });\n        }\n\n        [Fact]\n        public async Task TestUploadApplicationBinaries_NonExistingBinariesDir()\n        {\n            const string testName = nameof(TestUploadApplicationBinaries_NonExistingBinariesDir);\n            await Assert.ThrowsAsync<BinariesNotFoundException>(async () =>\n            {\n                string localPath = Path.Combine(Path.GetTempPath(), testName);\n                await FileUtils.DeleteDirectoryIfAny(localPath);\n                await\n                    _deploymentRepository.UploadApplicationBinaries(TestAppIdentity, localPath, ConflictResolutionMode.OverwriteExistingBinaries);\n            });\n        }\n\n        [Fact]\n        public async Task TestHasBinaries()\n        {\n            Assert.False(await _deploymentRepository.HasApplicationBinaries(TestAppIdentity));\n            await UploadTestApplicationBinaries(ConflictResolutionMode.FailIfBinariesExist, \"some json\");\n            Assert.True(await _deploymentRepository.HasApplicationBinaries(TestAppIdentity));\n        }\n\n        [Fact]\n        public async Task TestDeleteApplicationBinaries()\n        {\n            await UploadTestApplicationBinaries(ConflictResolutionMode.FailIfBinariesExist, \"some json\");\n            await _deploymentRepository.DeleteApplicationBinaries(TestAppIdentity);\n            CloudBlobContainer applicationsContainer =\n                _blobClient.GetContainerReference(BlobStorageDeploymentRepository.ApplicationsRootFolderName);\n            Assert.False(await applicationsContainer.GetDirectoryReference(TestAppId).ExistsAsync());\n        }\n\n        [Fact]\n        public async Task TestDeleteNonExistingApplicationBinaries()\n        {\n            await Assert.ThrowsAsync<BinariesNotFoundException>(async () =>\n                await _deploymentRepository.DeleteApplicationBinaries(TestAppIdentity));\n        }\n\n        [Fact]\n        public async Task TestDownloadApplicationBinaries()\n        {\n            const string testName = nameof(TestDownloadApplicationBinaries);\n            const string testFileContent = \"some content\";\n            await UploadTestApplicationBinaries(ConflictResolutionMode.FailIfBinariesExist, testFileContent);\n            string localPath = await CreateTestTempDirectory(testName);\n            await _deploymentRepository.DownloadApplicationBinaries(TestAppIdentity, localPath, ConflictResolutionMode.FailIfBinariesExist);\n            VerifyBinariesExist(localPath, testFileContent);\n        }\n\n        [Fact]\n        public async Task TestDownloadApplicationBinaries_ConflictResolutionMode()\n        {\n            // setup\n            const string testName = nameof(ConflictResolutionMode);\n            string localPath = await CreateTestTempDirectory(testName);\n            CreateTestFile(localPath, \"original content\");\n            VerifyBinariesExist(localPath, \"original content\");\n\n            await UploadTestApplicationBinaries(ConflictResolutionMode.FailIfBinariesExist, \"new content\");\n            await\n                _deploymentRepository.DownloadApplicationBinaries(TestAppIdentity, localPath,\n                    ConflictResolutionMode.DoNothingIfBinariesExist);\n            VerifyBinariesExist(localPath, \"original content\");\n\n            await\n                _deploymentRepository.DownloadApplicationBinaries(TestAppIdentity, localPath,\n                    ConflictResolutionMode.OverwriteExistingBinaries);\n            VerifyBinariesExist(localPath, \"new content\");\n\n            await Assert.ThrowsAsync<DuplicateBinariesException>(async () =>\n                await\n                _deploymentRepository.DownloadApplicationBinaries(TestAppIdentity, localPath, ConflictResolutionMode.FailIfBinariesExist));\n        }\n\n        [Fact]\n        public async Task TestDownloadNonExistingApplicationBinaries()\n        {\n            const string testName = nameof(TestDownloadNonExistingApplicationBinaries);\n            await Assert.ThrowsAsync<BinariesNotFoundException>(async () =>\n            {\n                string localPath = await CreateTestTempDirectory(testName);\n                await\n                    _deploymentRepository.DownloadApplicationBinaries(TestAppIdentity, localPath,\n                        ConflictResolutionMode.OverwriteExistingBinaries);\n            });\n        }\n\n        private static async Task VerifyBlobStorageContent(string someJsonContent)\n        {\n            CloudBlobContainer applicationsContainer =\n                _blobClient.GetContainerReference(BlobStorageDeploymentRepository.ApplicationsRootFolderName);\n            CloudBlobDirectory appDirectory = applicationsContainer.GetDirectoryReference(TestAppBlobRelPath);\n            Assert.Equal(1, (await appDirectory.ListBlobsAsync()).Count());\n            Assert.Equal(someJsonContent,\n                await appDirectory.GetBlockBlobReference(TestAppFileName).DownloadTextAsync());\n        }\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        public string GetCurrentMethodName()\n        {\n            StackTrace st = new StackTrace();\n            StackFrame sf = st.GetFrame(1);\n            return sf.GetMethod().Name;\n        }\n\n        private static void VerifyBinariesExist(string path, string testFileContent)\n        {\n            Assert.Equal(1, FileUtils.ListFilesRecursively(path).Count());\n            Assert.Equal(testFileContent, File.ReadAllText(Path.Combine(path, TestAppFileName)));\n        }\n\n        private static async Task UploadTestApplicationBinaries(ConflictResolutionMode conflictResolutionMode, string testFileContent)\n        {\n            string testDir = await CreateTestTempDirectory(nameof(UploadTestApplicationBinaries));\n            CreateTestFile(testDir, testFileContent);\n\n            await _deploymentRepository.UploadApplicationBinaries(TestAppIdentity, testDir, conflictResolutionMode);\n        }\n\n        private static void CreateTestFile(string testDir, string testFileContent)\n        {\n            string appConfigPath = Path.Combine(testDir, TestAppFileName);\n            File.WriteAllText(appConfigPath, testFileContent);\n        }\n\n        private static async Task<string> CreateTestTempDirectory(string testName)\n        {\n            string tempPath = Path.Combine(Path.GetTempPath(), testName);\n            await FileUtils.DeleteDirectoryIfAny(tempPath);\n            Directory.CreateDirectory(tempPath);\n            return tempPath;\n        }\n    }\n}"
  },
  {
    "path": "test/AzureBlobStorageDeploymentRepositoryTest/Data/DeploymentRepository/DeploymentConfig.json",
    "content": "﻿{\n  \"Applications\": [\n    {\n      \"Id\": \"app1\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ]\n    },\n    {\n      \"Id\": \"app1\",\n      \"Version\": \"1.0.1\",\n      \"TargetClusters\": [ \"clusterId1\", \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"app2\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ]\n    },\n    {\n      \"Id\": \"app3\",\n      \"Version\": \"2.0.0\",\n      \"TargetClusters\": [ \"clusterId3\" ]\n    }\n  ]\n}"
  },
  {
    "path": "test/AzureBlobStorageDeploymentRepositoryTest/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"AzureBlobStorageDeploymentRepositoryTest\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"AzureBlobStorageDeploymentRepositoryTest\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"e66f281c-bd50-45b0-aaef-fb87e4c9d0cc\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/AzureBlobStorageDeploymentRepositoryTest/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n    </assemblyBinding>\n  </runtime>\n</configuration>"
  },
  {
    "path": "test/AzureBlobStorageDeploymentRepositoryTest/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net461\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net461\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net461\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net461\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net461\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net461\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net461\" />\n  <package id=\"xunit\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.abstractions\" version=\"2.0.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.assert\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.core\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.extensibility.core\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.extensibility.execution\" version=\"2.1.0\" targetFramework=\"net45\" />\n</packages>"
  },
  {
    "path": "test/AzureBlobStorageUpdateSessionTest/AzureBlobStorageUpdateSessionTest.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{9C0602C2-00DD-43F4-B274-6598AF33C00A}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Azure.Test</RootNamespace>\n    <AssemblyName>AzureBlobStorageUpdateSessionTest</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n    <VisualStudioVersion Condition=\"'$(VisualStudioVersion)' == ''\">10.0</VisualStudioVersion>\n    <VSToolsPath Condition=\"'$(VSToolsPath)' == ''\">$(MSBuildExtensionsPath32)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)</VSToolsPath>\n    <ReferencePath>$(ProgramFiles)\\Common Files\\microsoft shared\\VSTT\\$(VisualStudioVersion)\\UITestExtensionPackages</ReferencePath>\n    <IsCodedUITest>False</IsCodedUITest>\n    <TestProjectType>UnitTest</TestProjectType>\n    <TargetFrameworkProfile />\n    <NuGetPackageImportStamp>\n    </NuGetPackageImportStamp>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.SimpleStubs, Version=0.0.1.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Etg.SimpleStubs.2.3.1\\lib\\net46\\Etg.SimpleStubs.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.QualityTools.Testing.Fakes, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n      <SpecificVersion>False</SpecificVersion>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.abstractions.2.0.0\\lib\\net35\\xunit.abstractions.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.assert, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.assert.2.1.0\\lib\\dotnet\\xunit.assert.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.core, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.core.2.1.0\\lib\\dotnet\\xunit.core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.execution.desktop, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.execution.2.1.0\\lib\\net45\\xunit.execution.desktop.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n  </ItemGroup>\n  <Choose>\n    <When Condition=\"('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'\">\n      <ItemGroup>\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\" />\n      </ItemGroup>\n    </When>\n    <Otherwise>\n      <ItemGroup>\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.UnitTestFramework\">\n          <Private>False</Private>\n        </Reference>\n      </ItemGroup>\n    </Otherwise>\n  </Choose>\n  <ItemGroup>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Properties\\SimpleStubs.generated.cs\" />\n    <Compile Include=\"UpdateSession\\Retry\\UpdateBlobFactoryRetryLockDecoratorTest.cs\" />\n    <Compile Include=\"UpdateSession\\Retry\\UpdateSessionManagerRetryDecoratorTest.cs\" />\n    <Compile Include=\"UpdateSession\\AzureTableUpdateSessionManagerTests.cs\" />\n    <Compile Include=\"UpdateSession\\UpdateBlobTest.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\AzureBlobStorageUpdateSession\\AzureBlobStorageUpdateSession.csproj\">\n      <Project>{894b7986-5aa4-42a7-8eb0-6dfd1f604505}</Project>\n      <Name>AzureBlobStorageUpdateSession</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\AzureUtils\\AzureUtils.csproj\">\n      <Project>{1c890e49-5a9b-4eab-9f69-6a6e78d82610}</Project>\n      <Name>AzureUtils</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Core\\Etg.Yams.Core.csproj\">\n      <Project>{7145e485-34fa-4632-89b0-bd27c96af69c}</Project>\n      <Name>Etg.Yams.Core</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\AzureTestUtils\\AzureTestUtils.csproj\">\n      <Project>{84c08621-2c78-4b19-9454-7b9019e68326}</Project>\n      <Name>AzureTestUtils</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Stubs\\Stubs.csproj\">\n      <Project>{68cd41f8-a6c3-4d43-93ca-92e898254cbd}</Project>\n      <Name>Stubs</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\TestUtils\\TestUtils.csproj\">\n      <Project>{c25452e1-aff2-4579-b6b4-f040cad02fda}</Project>\n      <Name>TestUtils</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\">\n      <SubType>Designer</SubType>\n    </None>\n    <None Include=\"SimpleStubs.json\" />\n  </ItemGroup>\n  <Choose>\n    <When Condition=\"'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'\">\n      <ItemGroup>\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n      </ItemGroup>\n    </When>\n  </Choose>\n  <Import Project=\"$(VSToolsPath)\\TeamTest\\Microsoft.TestTools.targets\" Condition=\"Exists('$(VSToolsPath)\\TeamTest\\Microsoft.TestTools.targets')\" />\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <Import Project=\"..\\..\\packages\\Etg.SimpleStubs.2.3.1\\build\\Etg.SimpleStubs.targets\" Condition=\"Exists('..\\..\\packages\\Etg.SimpleStubs.2.3.1\\build\\Etg.SimpleStubs.targets')\" />\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\..\\packages\\Etg.SimpleStubs.2.3.1\\build\\Etg.SimpleStubs.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\packages\\Etg.SimpleStubs.2.3.1\\build\\Etg.SimpleStubs.targets'))\" />\n  </Target>\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/AzureBlobStorageUpdateSessionTest/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"AzureBlobStorageUpdateSessionTest\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"AzureBlobStorageUpdateSessionTest\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"9c0602c2-00dd-43f4-b274-6598af33c00a\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/AzureBlobStorageUpdateSessionTest/SimpleStubs.json",
    "content": "{\n  \"IgnoredProjects\": [\n    \"Stubs\",\n    \"AzureBlobStorageUpdateSession\",\n    \"Etg.Yams.Core\",\n    \"AzureTestUtils\",\n    \"AzureUtils\"\n  ],\n    \"IgnoredInterfaces\": [\n    ],\n\t\"StubInternalInterfaces\": false\n}"
  },
  {
    "path": "test/AzureBlobStorageUpdateSessionTest/UpdateSession/AzureTableUpdateSessionManagerTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Autofac;\nusing Etg.SimpleStubs;\nusing Etg.Yams.Azure.UpdateSession;\nusing Etg.Yams.AzureTestUtils.Fixtures;\nusing Etg.Yams.TestUtils;\nusing Etg.Yams.Update;\nusing Microsoft.WindowsAzure.Storage;\nusing Microsoft.WindowsAzure.Storage.Table;\nusing Xunit;\n\nnamespace Etg.Yams.Azure.Test.UpdateSession\n{\n    [Trait(\"Category\", \"Integration\")]\n    public class AzureTableUpdateSessionManagerTests : IClassFixture<AzureStorageEmulatorTestFixture>\n    {\n        private const string EmulatorConnectionString = \"UseDevelopmentStorage=true\";\n        private readonly IUpdateSessionManager _updateSessionManager;\n\n        private static readonly TimeSpan Ttl = TimeSpan.FromMinutes(1);\n\n        public AzureTableUpdateSessionManagerTests(AzureStorageEmulatorTestFixture fixture)\n        {\n            fixture.ClearBlobStorage();\n\n            CloudTableClient client = CloudStorageAccount.Parse(EmulatorConnectionString).CreateCloudTableClient();\n            var table = client.GetTableReference(AzureTableUpdateSessionManager.UpdateSessionTableName);\n            table.DeleteIfExists();\n\n            _updateSessionManager = CreateUpdateSessionManager(\"superClusterId\", \"instanceId1\", \"1\");\n        }\n\n        [Fact]\n        public async Task TestStartUpdateSessionSimple()\n        {\n            Assert.True(await _updateSessionManager.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestThatOnlyOneUpdateDomainCanUpdateAtATime()\n        {\n            Assert.True(await _updateSessionManager.TryStartUpdateSession());\n            IUpdateSessionManager otherUpdateSessionManager = CreateUpdateSessionManager(\"superClusterId\", \"instanceId2\", \"2\");\n            Assert.False(await otherUpdateSessionManager.TryStartUpdateSession());\n        }\n\n        private static IUpdateSessionManager CreateUpdateSessionManager(string superClusterId, string instanceId, string updateDomain)\n        {\n            var updateSessionTable = new UpdateSessionTable(EmulatorConnectionString, ttl: TimeSpan.FromMinutes(1));\n            return new AzureTableUpdateSessionManager(updateSessionTable, superClusterId, instanceId, updateDomain);\n        }\n\n        [Fact]\n        public async Task TestThatMultipleInstancesInTheSameUpdateDomainCanUpdateSimultaneously()\n        {\n            Assert.True(await _updateSessionManager.TryStartUpdateSession());\n\n            IUpdateSessionManager otherUpdateSessionManager = CreateUpdateSessionManager(\"superClusterId\", \"instanceId2\", \"1\");\n            Assert.True(await otherUpdateSessionManager.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestThatEndUpdateSessionWorks()\n        {\n            Assert.True(await _updateSessionManager.TryStartUpdateSession());\n\n            await _updateSessionManager.EndUpdateSession();\n\n            IUpdateSessionManager otherUpdateSessionManager = CreateUpdateSessionManager(\"superClusterId\", \"instanceId2\", \"2\");\n            Assert.True(await otherUpdateSessionManager.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestThatDifferentDeploymentsCanUpdateIndependently()\n        {\n            Assert.True(await _updateSessionManager.TryStartUpdateSession());\n\n            IUpdateSessionManager otherUpdateSessionManager = CreateUpdateSessionManager(\"superClusterId2\", \"instanceId2\", \"2\");\n            Assert.True(await otherUpdateSessionManager.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestThatMultipleAppsCanUpdateSimultaneously()\n        {\n            Assert.True(await _updateSessionManager.TryStartUpdateSession());\n            Assert.True(await _updateSessionManager.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestEdgeCase_InstanceEnlists_SetUpdateDomain_Race()\n        {\n            Assert.True(await _updateSessionManager.TryStartUpdateSession());\n            await _updateSessionManager.EndUpdateSession();\n\n            IUpdateSessionTable updateSessionTable = new UpdateSessionTable(EmulatorConnectionString, Ttl);\n\n            var updateSessionTableStub = ReplaceExecuteTransactionImplementation(updateSessionTable,\n                async transaction =>\n                {\n                    // enlist another instance right before changing the update domain\n                    await _updateSessionManager.TryStartUpdateSession();\n                    return await updateSessionTable.TryExecuteTransaction(transaction);\n                });\n\n            var updateSessionManager = new AzureTableUpdateSessionManager(updateSessionTableStub, \"superClusterId\", \"instanceId2\", \"2\");\n            Assert.False(await updateSessionManager.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestEdgeCase_InstanceEnlists_InsertUpdateDomain_Race()\n        {\n            var updateSessionTable = new UpdateSessionTable(EmulatorConnectionString, Ttl);\n\n            var updateSessionTableStub = ReplaceExecuteTransactionImplementation(updateSessionTable,\n                async transaction =>\n                {\n                    // enlist another instance right before changing the update domain\n                    await _updateSessionManager.TryStartUpdateSession();\n                    return await updateSessionTable.TryExecuteTransaction(transaction);\n                });\n\n            var updateSessionManager = new AzureTableUpdateSessionManager(updateSessionTableStub, \"superClusterId\", \"instanceId2\", \"2\");\n            Assert.False(await updateSessionManager.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestEdgeCase_SetUpdateDomainRace()\n        {\n            Assert.True(await _updateSessionManager.TryStartUpdateSession());\n            await _updateSessionManager.EndUpdateSession();\n\n            var updateSessionTable = new UpdateSessionTable(EmulatorConnectionString, Ttl);\n\n            var updateSessionTableStub = ReplaceExecuteTransactionImplementation(updateSessionTable,\n                async transaction =>\n                {\n                    // set update domain 3 right before update domain 2 is being set\n                    var updateSession =\n                        new AzureTableUpdateSessionManager(updateSessionTable, \"superClusterId\", \"instanceId3\", \"3\");\n                    Assert.True(await updateSession.TryStartUpdateSession());\n\n                    return await updateSessionTable.TryExecuteTransaction(transaction);\n                });\n\n            var updateSessionManager = new AzureTableUpdateSessionManager(updateSessionTableStub, \"superClusterId\", \"instanceId2\", \"2\");\n            Assert.False(await updateSessionManager.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestEdgeCase_InsertUpdateDomainRace()\n        {\n            var updateSessionTable = new UpdateSessionTable(EmulatorConnectionString, Ttl);\n\n            var updateSessionTableStub = ReplaceExecuteTransactionImplementation(updateSessionTable,\n                async transaction =>\n                {\n                    Assert.True(await _updateSessionManager.TryStartUpdateSession());\n                    return await updateSessionTable.TryExecuteTransaction(transaction);\n                });\n\n            var updateSessionManager = new AzureTableUpdateSessionManager(updateSessionTableStub, \"superClusterId\", \"instanceId2\", \"2\");\n            Assert.False(await updateSessionManager.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestThatStorageExceptionsAreRetried()\n        {\n            var fetchUpdateSessionStatusStub = StubsUtils.Sequence<Func<Task<UpdateSessionStatus>>>()\n                .Once(() => AsyncUtils.AsyncTaskThatThrows<UpdateSessionStatus>(new StorageException()))\n                .Once(() => Task.FromResult(new UpdateSessionStatus(Enumerable.Empty<UpdateDomainEntity>(), null, null)));\n\n            IUpdateSessionTable updateSessionTableStub = new StubIUpdateSessionTable()\n                .FetchUpdateSessionStatus((superClusterId) => fetchUpdateSessionStatusStub.Next())\n                .TryExecuteTransaction(transaction => Task.FromResult(true))\n                .DeleteInstanceEntity((superClusterId, instanceId) => Task.FromResult(true))\n                .GetActiveUpdateDomain((superClusterId) => Task.FromResult(\"1\"));\n\n            ContainerBuilder builder = AzureStorageUpdateSessionDiModule.RegisterTypes(\"superClusterId\", \"superClusterId\",\n                \"instanceId\", \"1\", EmulatorConnectionString, Ttl);\n            builder.RegisterInstance(updateSessionTableStub);\n            IUpdateSessionManager updateSessionManager = new AzureStorageUpdateSessionDiModule(builder.Build())\n                .UpdateSessionManager;\n            Assert.True(await updateSessionManager.TryStartUpdateSession());\n            \n            await updateSessionManager.EndUpdateSession();\n\n            Assert.Equal(2, fetchUpdateSessionStatusStub.CallCount);\n        }\n\n        private IUpdateSessionTable ReplaceExecuteTransactionImplementation(IUpdateSessionTable updateSessionTable,\n            StubIUpdateSessionTable.TryExecuteTransaction_UpdateSessionTransaction_Delegate del)\n        {\n            IUpdateSessionTable updateSessionTableStub = new StubIUpdateSessionTable()\n                .FetchUpdateSessionStatus(updateSessionTable.FetchUpdateSessionStatus)\n                .TryExecuteTransaction(del)\n                .DeleteInstanceEntity(updateSessionTable.DeleteInstanceEntity)\n                .GetActiveUpdateDomain(updateSessionTable.GetActiveUpdateDomain);\n            return updateSessionTableStub;\n        }\n    }\n}\n"
  },
  {
    "path": "test/AzureBlobStorageUpdateSessionTest/UpdateSession/Retry/UpdateBlobFactoryRetryLockDecoratorTest.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Etg.SimpleStubs;\nusing Etg.Yams.Azure.UpdateSession;\nusing Etg.Yams.Azure.UpdateSession.Retry;\nusing Etg.Yams.TestUtils;\nusing Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;\nusing Xunit;\n\nnamespace Etg.Yams.Azure.Test.UpdateSession.Retry\n{\n    public class UpdateBlobFactoryRetryLockDecoratorTest\n    {\n        [Fact]\n        public async Task TestSuccessfullRetry()\n        {\n            string appId = \"appId\";\n            IUpdateBlob updateBlob = new StubIUpdateBlob();\n\n            var sequence = StubsUtils.Sequence<StubIUpdateBlobFactory.TryLockUpdateBlob_String_Delegate>()\n                .Twice(id => AsyncUtils.AsyncTaskThatThrows<IUpdateBlob>(new UpdateBlobUnavailableException()))\n                .Once(id => AsyncUtils.AsyncTaskWithResult(updateBlob));\n\t        var updateBlobFactoryStub = new StubIUpdateBlobFactory()\n\t\t        .TryLockUpdateBlob(id => sequence.Next(appId));\n\n            UpdateBlobFactoryRetryLockDecorator retryDecorator =\n                new UpdateBlobFactoryRetryLockDecorator(updateBlobFactoryStub,\n                    new FixedInterval(2, TimeSpan.Zero));\n            Assert.Equal(updateBlob, await retryDecorator.TryLockUpdateBlob(appId));\n        }\n\n        [Fact]\n        public async Task TestThatExceptionIsThrownIfMaxRetryCountIsReached()\n        {\n            string appId = \"appId\";\n            IUpdateBlob updateBlob = new StubIUpdateBlob();\n\n            var sequence = StubsUtils.Sequence<StubIUpdateBlobFactory.TryLockUpdateBlob_String_Delegate>()\n                .Twice(id => AsyncUtils.AsyncTaskThatThrows<IUpdateBlob>(new UpdateBlobUnavailableException()))\n                .Once(id => AsyncUtils.AsyncTaskWithResult(updateBlob));\n\t        var updateBlobFactoryStub = new StubIUpdateBlobFactory()\n\t\t        .TryLockUpdateBlob(id => sequence.Next(appId));\n\n            UpdateBlobFactoryRetryLockDecorator retryDecorator =\n                new UpdateBlobFactoryRetryLockDecorator(updateBlobFactoryStub, new FixedInterval(1, TimeSpan.Zero));\n            await\n                Assert.ThrowsAsync<UpdateBlobUnavailableException>(\n                    async () => await retryDecorator.TryLockUpdateBlob(appId));\n        }\n\n        [Fact]\n        public async Task TestThatNotAllExceptionsAreRetried()\n        {\n            string appId = \"appId\";\n\n            var sequence = StubsUtils.Sequence<StubIUpdateBlobFactory.TryLockUpdateBlob_String_Delegate>()\n                .Twice(id => AsyncUtils.AsyncTaskThatThrows<IUpdateBlob>(new Exception()));\n            var updateBlobFactoryStub = new StubIUpdateBlobFactory()\n\t\t\t\t.TryLockUpdateBlob(id => sequence.Next(appId));\n\n            UpdateBlobFactoryRetryLockDecorator retryDecorator =\n                new UpdateBlobFactoryRetryLockDecorator(updateBlobFactoryStub, new FixedInterval(1, TimeSpan.Zero));\n            await\n                Assert.ThrowsAsync<Exception>(async () => await retryDecorator.TryLockUpdateBlob(appId));\n        }\n    }\n}"
  },
  {
    "path": "test/AzureBlobStorageUpdateSessionTest/UpdateSession/Retry/UpdateSessionManagerRetryDecoratorTest.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Etg.SimpleStubs;\nusing Etg.Yams.Azure.UpdateSession.Retry;\nusing Etg.Yams.TestUtils;\nusing Etg.Yams.Update;\nusing Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;\nusing Microsoft.WindowsAzure.Storage;\nusing Xunit;\n\nnamespace Etg.Yams.Azure.Test.UpdateSession.Retry\n{\n    public class UpdateSessionManagerRetryDecoratorTest\n    {\n        [Fact]\n        public async Task TestThatStartUpdateSessionIsRetried()\n        {\n            var sequence = StubsUtils.Sequence<StubIUpdateSessionManager.TryStartUpdateSession_Delegate>()\n                .Once(() => AsyncUtils.AsyncTaskThatThrows<bool>(new StorageException()))\n                .Once(() => AsyncUtils.AsyncTaskWithResult(true));\n\n\t        var updateSessionStub = new StubIUpdateSessionManager()\n\t\t        .TryStartUpdateSession(() => sequence.Next());\n\n            IUpdateSessionManager retryDecorator = new StorageExceptionUpdateSessionRetryDecorator(\n                updateSessionStub,\n                new FixedInterval(1, TimeSpan.Zero),\n                new StorageExceptionErrorDetectionStrategy());\n            Assert.True(await retryDecorator.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestThatEndUpdateSessionIsRetried()\n        {\n            var sequence = StubsUtils.Sequence<StubIUpdateSessionManager.EndUpdateSession_Delegate>()\n                .Once(() => AsyncUtils.AsyncTaskThatThrows(new StorageException()))\n                .Once(() => Task.CompletedTask);\n\n\t        var updateSessionStub = new StubIUpdateSessionManager()\n\t\t        .EndUpdateSession(() => sequence.Next());\n\n            IUpdateSessionManager retryDecorator = new StorageExceptionUpdateSessionRetryDecorator(\n                updateSessionStub,\n                new FixedInterval(1, TimeSpan.Zero),\n                new StorageExceptionErrorDetectionStrategy());\n            await retryDecorator.EndUpdateSession();\n        }\n\n        [Fact]\n        public async Task TestThatExceptionIsThrownIfMaxRetryCountIsReached()\n        {\n            var sequence = StubsUtils.Sequence<StubIUpdateSessionManager.TryStartUpdateSession_Delegate>()\n                .Twice(() => AsyncUtils.AsyncTaskThatThrows<bool>(new StorageException()))\n                .Once(() => AsyncUtils.AsyncTaskWithResult(true));\n\n\t        var updateSessionStub = new StubIUpdateSessionManager()\n\t\t        .TryStartUpdateSession(() => sequence.Next());\n\n            IUpdateSessionManager retryDecorator = new StorageExceptionUpdateSessionRetryDecorator(\n                updateSessionStub,\n                new FixedInterval(1, TimeSpan.Zero),\n                new StorageExceptionErrorDetectionStrategy());\n            await Assert.ThrowsAsync<StorageException>(async () => await retryDecorator.TryStartUpdateSession());\n        }\n\n        [Fact]\n        public async Task TestThatNotAllExceptionsAreRetried()\n        {\n\t        var updateSessionStub = new StubIUpdateSessionManager()\n\t\t        .TryStartUpdateSession(() => AsyncUtils.AsyncTaskThatThrows<bool>(new Exception()));\n\n            IUpdateSessionManager retryDecorator = new StorageExceptionUpdateSessionRetryDecorator(\n                updateSessionStub,\n                new FixedInterval(1, TimeSpan.Zero),\n                new StorageExceptionErrorDetectionStrategy());\n            await Assert.ThrowsAsync<Exception>(async () => await retryDecorator.TryStartUpdateSession());\n        }\n    }\n}"
  },
  {
    "path": "test/AzureBlobStorageUpdateSessionTest/UpdateSession/UpdateBlobTest.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Etg.Yams.Azure.Lease;\nusing Etg.Yams.Azure.UpdateSession;\nusing Etg.Yams.Azure.Utils;\nusing Etg.Yams.AzureTestUtils.Fixtures;\nusing Etg.Yams.TestUtils;\nusing Microsoft.WindowsAzure.Storage;\nusing Microsoft.WindowsAzure.Storage.Blob;\nusing Xunit;\n\nnamespace Etg.Yams.Azure.Test.UpdateSession\n{\n    [Trait(\"Category\", \"Integration\")]\n    public class UpdateBlobTest : IClassFixture<AzureStorageEmulatorTestFixture>\n    {\n        private readonly UpdateBlobFactory _updateBlobFactory;\n        private readonly CloudBlobContainer _container;\n\n        public UpdateBlobTest(AzureStorageEmulatorTestFixture fixture)\n        {\n            fixture.ClearBlobStorage();\n            var blobClient = fixture.BlobClient;\n            const string containerName = \"container\";\n            _container = blobClient.GetContainerReference(containerName);\n            _container.CreateIfNotExists();\n            _updateBlobFactory = new UpdateBlobFactory(\"clusterId\", _container, new BlobLeaseFactory());\n        }\n\n        [Fact]\n        public async Task TestSetDataWhenBlobIsEmpty()\n        {\n            IUpdateBlob updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n\n            const string instanceId = \"instanceId\";\n            const string updateDomain = \"1\";\n            updateBlob.SetUpdateDomain(updateDomain);\n            updateBlob.AddInstance(instanceId);\n            await updateBlob.FlushAndRelease();\n\n            await updateBlob.TryLock();\n            Assert.Equal(updateDomain, updateBlob.GetUpdateDomain());\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { instanceId }, updateBlob.GetInstanceIds());\n        }\n\n        [Fact]\n        public async Task TestAddingMultipleInstanceIds()\n        {\n            IUpdateBlob updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n\n            updateBlob.SetUpdateDomain(\"1\");\n            updateBlob.AddInstance(\"instanceId1\");\n            updateBlob.AddInstance(\"instanceId2\");\n            await updateBlob.FlushAndRelease();\n\n            await updateBlob.TryLock();\n            Assert.Equal(\"1\", updateBlob.GetUpdateDomain());\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"instanceId1\", \"instanceId2\" }, updateBlob.GetInstanceIds());\n        }\n\n        [Fact]\n        public async Task TestRemoveInstanceId()\n        {\n            IUpdateBlob updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n\n            updateBlob.SetUpdateDomain(\"1\");\n            updateBlob.AddInstance(\"instanceId1\");\n            updateBlob.AddInstance(\"instanceId2\");\n            await updateBlob.FlushAndRelease();\n\n            updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n            updateBlob.RemoveInstance(\"instanceId1\");\n            await updateBlob.FlushAndRelease();\n\n            await updateBlob.TryLock();\n            Assert.Equal(\"1\", updateBlob.GetUpdateDomain());\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"instanceId2\" }, updateBlob.GetInstanceIds());\n            await updateBlob.Release();\n\n            updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n            updateBlob.RemoveInstance(\"instanceId2\");\n            await updateBlob.FlushAndRelease();\n\n            await updateBlob.TryLock();\n            Assert.True(string.IsNullOrEmpty(updateBlob.GetUpdateDomain()));\n            Assert.Empty(updateBlob.GetInstanceIds());\n        }\n\n        [Fact]\n        public async Task TestGetUpdateDomainOnEmptyBlob()\n        {\n            IUpdateBlob updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n            Assert.True(string.IsNullOrEmpty(updateBlob.GetUpdateDomain()));\n        }\n\n        [Fact]\n        public async Task TestGetInstanceIdsOnEmptyBlob()\n        {\n            IUpdateBlob updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n            Assert.Empty(updateBlob.GetInstanceIds());\n        }\n\n        [Fact]\n        public async Task TestThatUpdateBlobMustBeLockedBeforeAnyOperation()\n        {\n            IUpdateBlob updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n            await updateBlob.FlushAndRelease();\n            Assert.Throws<InvalidOperationException>(() => updateBlob.GetUpdateDomain());\n            Assert.Throws<InvalidOperationException>(() => updateBlob.GetInstanceIds());\n            Assert.Throws<InvalidOperationException>(() => updateBlob.AddInstance(\"1\"));\n            Assert.Throws<InvalidOperationException>(() => updateBlob.RemoveInstance(\"1\"));\n            Assert.Throws<InvalidOperationException>(() => updateBlob.SetUpdateDomain(\"1\"));\n            await Assert.ThrowsAsync<InvalidOperationException>(async () => await updateBlob.FlushAndRelease());\n        }\n\n        [Fact]\n        public async Task TestFlushWhenInstanceAreSetButNoUpdateDomain()\n        {\n            IUpdateBlob updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n            updateBlob.AddInstance(\"instanceId1\");\n            await Assert.ThrowsAsync<InvalidOperationException>(async () => await updateBlob.FlushAndRelease());\n        }\n\n        [Fact]\n        public async Task TestThatDisposeReleasesTheLease()\n        {\n            IUpdateBlob updateBlob = await _updateBlobFactory.TryLockUpdateBlob(\"appId\");\n            updateBlob.Dispose();\n            Assert.NotNull(await _updateBlobFactory.TryLockUpdateBlob(\"appId\"));\n        }\n\n        [Fact]\n        public async Task TestThatLockFailsIfBlobLeaseReturnsNull()\n        {\n            var blobLeaseStub = new StubIBlobLease()\n                .TryAcquireLease(() => AsyncUtils.AsyncTaskWithResult<string>(null))\n                .Dispose(() => { }\n            );\n            await TestThatLockFailsIfBlobLeaseCantBeAcquired(blobLeaseStub);\n        }\n\n        [Fact]\n        public async Task TestThatLockFailsIfBlobLeaseThrowsStorageException()\n        {\n            var blobLeaseStub = new StubIBlobLease()\n                .TryAcquireLease (() => AsyncUtils.AsyncTaskThatThrows<string>(new StorageException()))\n                .Dispose(() => { }\n            );\n            await TestThatLockFailsIfBlobLeaseCantBeAcquired(blobLeaseStub);\n        }\n\n        private async Task TestThatLockFailsIfBlobLeaseCantBeAcquired(IBlobLease blobLeaseStub)\n        {\n\n\t        var leaseFactoryMock = new StubIBlobLeaseFactory()\n\t\t        .CreateLease(blob => blobLeaseStub);\n\n            var testBlob = _container.GetBlockBlobReference(\"testBlob\");\n            await BlobUtils.CreateEmptyBlob(testBlob);\n            UpdateBlob updateBlob = new UpdateBlob(testBlob, leaseFactoryMock);\n            Assert.False(await updateBlob.TryLock());\n        }\n    }\n}\n"
  },
  {
    "path": "test/AzureBlobStorageUpdateSessionTest/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net461\" />\n  <package id=\"EnterpriseLibrary.TransientFaultHandling\" version=\"6.0.1304.0\" targetFramework=\"net461\" />\n  <package id=\"Etg.SimpleStubs\" version=\"2.3.1\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net45\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net45\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net461\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net461\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net461\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net461\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net461\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net461\" />\n  <package id=\"xunit\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.abstractions\" version=\"2.0.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.assert\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.core\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.extensibility.core\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.extensibility.execution\" version=\"2.1.0\" targetFramework=\"net45\" />\n</packages>"
  },
  {
    "path": "test/AzureTestUtils/AzureStorageEmulatorProxy.cs",
    "content": "﻿using System;\nusing System.Configuration;\nusing System.Diagnostics;\nusing System.IO;\n\nnamespace Etg.Yams.AzureTestUtils\n{\n    public class AzureStorageEmulatorProxy\n    {\n        private const string DefaultStorageEmulatorLocation = @\"C:\\Program Files (x86)\\Microsoft SDKs\\Azure\\Storage Emulator\\AzureStorageEmulator.exe\";\n        private const string StorageEmulatorLocationKey = \"StorageEmulatorLocation\";\n        private readonly string _storageEmulatorLocation;\n\n        public AzureStorageEmulatorProxy()\n        {\n            _storageEmulatorLocation = ConfigurationManager.AppSettings[StorageEmulatorLocationKey];\n            if (_storageEmulatorLocation == null)\n            {\n                Trace.TraceWarning(\"Storage Emulator Location was not found in the app.config. The default location will be used\");\n                _storageEmulatorLocation = DefaultStorageEmulatorLocation;\n            }\n            Trace.TraceInformation(\"The Storage Emulator Location is \" + _storageEmulatorLocation);\n            if (!File.Exists(_storageEmulatorLocation))\n            {\n                throw new Exception(\"Could not find the storage emulator exe at \" + _storageEmulatorLocation);\n            }\n        }\n\n        public void StartEmulator()\n        {\n            ExecuteCommandOnEmulator(\"start\");\n        }\n\n        public void StopEmulator()\n        {\n            ExecuteCommandOnEmulator(\"stop\");\n        }\n\n        public void ClearBlobStorage()\n        {\n            ExecuteCommandOnEmulator(\"clear blob\");\n        }\n\n        private void ExecuteCommandOnEmulator(string arguments)\n        {\n            ProcessStartInfo start = new ProcessStartInfo\n            {\n                Arguments = arguments,\n                FileName = _storageEmulatorLocation,\n                RedirectStandardOutput = true,\n                UseShellExecute = false,\n                CreateNoWindow = true\n            };\n            Process proc = new Process\n            {\n                StartInfo = start\n            };\n            proc.Start();\n            proc.WaitForExit();\n        }\n    }\n}\n"
  },
  {
    "path": "test/AzureTestUtils/AzureTestUtils.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{84C08621-2C78-4B19-9454-7B9019E68326}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.AzureTestUtils</RootNamespace>\n    <AssemblyName>AzureTestUtils</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>Bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>Bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.configuration\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Fixtures\\AzureStorageEmulatorTestFixture.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"AzureStorageEmulatorProxy.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/AzureTestUtils/Fixtures/AzureStorageEmulatorTestFixture.cs",
    "content": "using Microsoft.WindowsAzure.Storage;\nusing Microsoft.WindowsAzure.Storage.Blob;\n\nnamespace Etg.Yams.AzureTestUtils.Fixtures\n{\n    public class AzureStorageEmulatorTestFixture\n    {\n        public CloudBlobClient BlobClient { get; }\n        private readonly AzureStorageEmulatorProxy _azureStorageEmulatorProxy;\n        public AzureStorageEmulatorTestFixture()\n        {\n            var account = CloudStorageAccount.DevelopmentStorageAccount;\n            BlobClient = account.CreateCloudBlobClient();\n\n            _azureStorageEmulatorProxy = new AzureStorageEmulatorProxy();\n            _azureStorageEmulatorProxy.StartEmulator();\n        }\n\n        public void ClearBlobStorage()\n        {\n            _azureStorageEmulatorProxy.ClearBlobStorage();\n        }\n\n        public void Dispose()\n        {\n            _azureStorageEmulatorProxy.StopEmulator();\n        }\n    }\n}"
  },
  {
    "path": "test/AzureTestUtils/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"AzureTestUtils\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"AzureTestUtils\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"84c08621-2c78-4b19-9454-7b9019e68326\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/AzureTestUtils/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net451\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net451\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net451\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net451\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "test/AzureUtilsTest/AzureUtilsTest.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{2FE963BD-D826-4CC5-8A63-864CDA212233}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Azure.Test</RootNamespace>\n    <AssemblyName>AzureUtilsTest</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n    <VisualStudioVersion Condition=\"'$(VisualStudioVersion)' == ''\">10.0</VisualStudioVersion>\n    <VSToolsPath Condition=\"'$(VSToolsPath)' == ''\">$(MSBuildExtensionsPath32)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)</VSToolsPath>\n    <ReferencePath>$(ProgramFiles)\\Common Files\\microsoft shared\\VSTT\\$(VisualStudioVersion)\\UITestExtensionPackages</ReferencePath>\n    <IsCodedUITest>False</IsCodedUITest>\n    <TestProjectType>UnitTest</TestProjectType>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.abstractions.2.0.0\\lib\\net35\\xunit.abstractions.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.assert, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.assert.2.1.0\\lib\\dotnet\\xunit.assert.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.core, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.core.2.1.0\\lib\\dotnet\\xunit.core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.execution.desktop, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.execution.2.1.0\\lib\\net45\\xunit.execution.desktop.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n  </ItemGroup>\n  <Choose>\n    <When Condition=\"('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'\">\n      <ItemGroup>\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\" />\n      </ItemGroup>\n    </When>\n    <Otherwise>\n      <ItemGroup>\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.UnitTestFramework\" />\n      </ItemGroup>\n    </Otherwise>\n  </Choose>\n  <ItemGroup>\n    <Compile Include=\"BlobUtilsTest.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\AzureUtils\\AzureUtils.csproj\">\n      <Project>{1c890e49-5a9b-4eab-9f69-6a6e78d82610}</Project>\n      <Name>AzureUtils</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Common\\Common.csproj\">\n      <Project>{3e982150-5b43-44da-8d96-66cf07a9a14c}</Project>\n      <Name>Common</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\AzureTestUtils\\AzureTestUtils.csproj\">\n      <Project>{84c08621-2c78-4b19-9454-7b9019e68326}</Project>\n      <Name>AzureTestUtils</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Choose>\n    <When Condition=\"'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'\">\n      <ItemGroup>\n        <Reference Include=\"Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n        <Reference Include=\"Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n          <Private>False</Private>\n        </Reference>\n      </ItemGroup>\n    </When>\n  </Choose>\n  <Import Project=\"$(VSToolsPath)\\TeamTest\\Microsoft.TestTools.targets\" Condition=\"Exists('$(VSToolsPath)\\TeamTest\\Microsoft.TestTools.targets')\" />\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/AzureUtilsTest/BlobUtilsTest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Etg.Yams.Azure.Utils;\nusing Etg.Yams.AzureTestUtils.Fixtures;\nusing Etg.Yams.Utils;\nusing Microsoft.WindowsAzure.Storage.Blob;\nusing Xunit;\n\nnamespace Etg.Yams.Azure.Test\n{\n    [Trait(\"Category\", \"Integration\")]\n    public class BlobUtilsTest : IClassFixture<AzureStorageEmulatorTestFixture>\n    {\n        private readonly CloudBlobClient _blobClient;\n\n        public BlobUtilsTest(AzureStorageEmulatorTestFixture fixture)\n        {\n            fixture.ClearBlobStorage();\n            _blobClient = fixture.BlobClient;\n        }\n\n        [Fact]\n        public async Task TestDownloadBlobsFromBlobDirectory()\n        {\n            // First create the file hierarchy in the blob storage\n            CloudBlobDirectory root = await CreateBlobsTree();\n\n            // The upload the directory to a local temporary folder\n            var tempPath = GetTestDirPath(nameof(TestDownloadBlobsFromBlobDirectory));\n            var appPath = Path.Combine(tempPath, \"app\\\\1.0.0\");\n            await BlobUtils.DownloadBlobDirectory(root, appPath);\n\n            ISet<string> relativePathSet = new HashSet<string>();\n            foreach (var path in FileUtils.ListFilesRecursively(appPath))\n            {\n                var relPath = FileUtils.GetRelativePath(appPath, path);\n                relativePathSet.Add(relPath);\n            }\n\n            // Then verify that the hierachy on the local file system matches the one in the blob directory\n            VerifyThatAllFilesAreThere(relativePathSet, \"\\\\\");\n\n            // get the modified data of d1/b1\n            string d1b1Path = Path.Combine(appPath, \"d1\", \"b1\");\n            DateTime d1b1WriteTime = File.GetLastWriteTimeUtc(d1b1Path);\n\n            // delete and modify some files to make sure that they will be download\n            File.Delete(Path.Combine(appPath, \"b1\"));\n            File.Delete(Path.Combine(appPath, \"d1\", \"b2\"));\n\n            // modify a file to make sure it'll be replaced\n            string b2FilePath = Path.Combine(appPath, \"b2\");\n            DateTime b2WriteTime = File.GetLastWriteTimeUtc(b2FilePath);\n            File.WriteAllText(b2FilePath, \"blabla\");\n            Assert.Equal(\"blabla\", File.ReadAllText(b2FilePath));\n\n            await BlobUtils.DownloadBlobDirectory(root, appPath);\n            VerifyThatAllFilesAreThere(relativePathSet, \"\\\\\");\n            string newFileContent = File.ReadAllText(b2FilePath);\n            Assert.Equal(d1b1WriteTime, File.GetLastWriteTimeUtc(d1b1Path));\n            Assert.NotEqual(b2WriteTime, File.GetLastWriteTimeUtc(b2FilePath));\n        }\n\n        private static ISet<string> ListFilesPath(string appPath)\n        {\n            ISet<string> relativePathSet = new HashSet<string>();\n            foreach (var path in FileUtils.ListFilesRecursively(appPath))\n            {\n                var relPath = FileUtils.GetRelativePath(appPath, path);\n                relativePathSet.Add(relPath);\n            }\n\n            return relativePathSet;\n        }\n\n        [Fact]\n        public async Task TestDeleteBlobDirectory()\n        {\n            // First create the file hierarchy in the blob storage\n            CloudBlobDirectory root = await CreateBlobsTree();\n            await root.DeleteAsync();\n\n            Assert.False(root.ListBlobs(true).Any());\n        }\n\n        [Fact]\n        public async Task TestUploadFile()\n        {\n            var container = _blobClient.GetContainerReference(\"container\");\n            container.CreateIfNotExists();\n\n            var testDirPath = GetTestDirPath(nameof(TestUploadFile));\n            var testFilePath = Path.Combine(testDirPath, \"testFile.txt\");\n            var testFileContent = \"TestUploadFileToBlob\";\n            File.WriteAllText(testFilePath, testFileContent);\n\n            var testBlobPath = \"testBlob.txt\";\n            await BlobUtils.UploadFile(testFilePath, container, testBlobPath);\n\n            var blob = container.GetBlockBlobReference(testBlobPath);\n            Assert.True(await blob.ExistsAsync());\n            Assert.Equal(testFileContent, await blob.DownloadTextAsync());\n        }\n\n        [Fact]\n        public async Task TestUploadDirectory()\n        {\n            // First create the file hierarchy on the local file system\n            var rootPath = await CreateLocalFileTree(nameof(TestUploadDirectory));\n\n            // Then upload the directory to blob storage\n            var container = _blobClient.GetContainerReference(\"container\");\n            container.CreateIfNotExists();\n            string blobDirPath = $\"{nameof(TestUploadDirectory)}/app/1.0.0\";\n            await BlobUtils.UploadDirectory(rootPath, container, blobDirPath);\n\n\n            var blobDirectory = container.GetDirectoryReference(blobDirPath);\n            var blobs = await blobDirectory.ListBlobsAsync();\n            ISet<string> relativePathSet = new HashSet<string>();\n            foreach (var blobItem in blobs)\n            {\n                var blob = (CloudBlockBlob) blobItem;\n                var relPath = BlobUtils.GetBlobRelativePath(blob, blobDirectory);\n                relativePathSet.Add(relPath);\n            }\n\n            // Then verify that the hierachy on the blob storage matches the one the local file system\n            VerifyThatAllFilesAreThere(relativePathSet, \"/\");\n        }\n\n        [Fact]\n        public async Task TestCreateBlobIfNotExists()\n        {\n            var container = _blobClient.GetContainerReference(\"container\");\n            container.CreateIfNotExists();\n            var blob = container.GetBlockBlobReference(\"createIfNotExistsTestBlob.txt\");\n            await BlobUtils.CreateBlobIfNotExists(blob);\n            Assert.True(await blob.ExistsAsync());\n            string text = \"test content\";\n            await blob.UploadTextAsync(text);\n\n            await BlobUtils.CreateBlobIfNotExists(blob);\n            Assert.Equal(text, await blob.DownloadTextAsync());\n        }\n\n        private static void VerifyThatAllFilesAreThere(ISet<string> relativePathSet, string separator)\n        {\n            Assert.Equal(9, relativePathSet.Count);\n            Assert.True(relativePathSet.Contains(\"b1\"));\n            Assert.True(relativePathSet.Contains(\"b2\"));\n            Assert.True(relativePathSet.Contains($\"d1{separator}b1\"));\n            Assert.True(relativePathSet.Contains($\"d1{separator}b2\"));\n            Assert.True(relativePathSet.Contains($\"d2{separator}b3\"));\n            Assert.True(relativePathSet.Contains($\"d2{separator}b4\"));\n            Assert.True(relativePathSet.Contains($\"d2{separator}d3{separator}b5\"));\n            Assert.True(relativePathSet.Contains($\"d2{separator}d3{separator}b6\"));\n            Assert.True(relativePathSet.Contains($\"d4{separator}d5{separator}b7\"));\n        }\n\n        private async Task<CloudBlobDirectory> CreateBlobsTree()\n        {\n            // root\n            // |__b1\n            // |__b2\n            // |__d1\n            // |  |__b1\n            // |  |__b2\n            // |__d2\n            // |  |__b3\n            // |  |__b4\n            // |  |__d3\n            // |  |  |__b5\n            // |  |  |__b6\n            // |__d4\n            // |  |__d5\n            // |  |  |__b7\n\n            var container = _blobClient.GetContainerReference(\"container\");\n            container.CreateIfNotExists();\n\n            var root = container.GetDirectoryReference(\"root\");\n\n            ICloudBlob b1 = root.GetBlockBlobReference(\"b1\");\n            await BlobUtils.CreateEmptyBlob(b1);\n\n            ICloudBlob b2 = root.GetBlockBlobReference(\"b2\");\n            await BlobUtils.CreateEmptyBlob(b2);\n\n            var d1 = root.GetDirectoryReference(\"d1\");\n            ICloudBlob d1b1 = d1.GetBlockBlobReference(\"b1\");\n            ICloudBlob d1b2 = d1.GetBlockBlobReference(\"b2\");\n            await BlobUtils.CreateEmptyBlob(d1b1);\n            await BlobUtils.CreateEmptyBlob(d1b2);\n\n            var d2 = root.GetDirectoryReference(\"d2\");\n            ICloudBlob d2b3 = d2.GetBlockBlobReference(\"b3\");\n            ICloudBlob d2b4 = d2.GetBlockBlobReference(\"b4\");\n            await BlobUtils.CreateEmptyBlob(d2b3);\n            await BlobUtils.CreateEmptyBlob(d2b4);\n\n            var d2d3 = d2.GetDirectoryReference(\"d3\");\n            ICloudBlob d2d3b5 = d2d3.GetBlockBlobReference(\"b5\");\n            ICloudBlob d2d3b6 = d2d3.GetBlockBlobReference(\"b6\");\n            await BlobUtils.CreateEmptyBlob(d2d3b5);\n            await BlobUtils.CreateEmptyBlob(d2d3b6);\n\n            await BlobUtils.CreateEmptyBlob(\n                root.GetDirectoryReference(\"d4\").GetDirectoryReference(\"d5\").GetBlockBlobReference(\"b7\"));\n            return root;\n        }\n\n        private async Task<string> CreateLocalFileTree(string testName)\n        {\n            // root\n            // |__b1\n            // |__b2\n            // |__d1\n            // |  |__b1\n            // |  |__b2\n            // |__d2\n            // |  |__b3\n            // |  |__b4\n            // |  |__d3\n            // |  |  |__b5\n            // |  |  |__b6\n            // |__d4\n            // |  |__d5\n            // |  |  |__b7\n\n            var testDirPath = GetTestDirPath(testName);\n            var rootPath = Path.Combine(testDirPath, \"root\");\n\n            await CreateNewDirectory(rootPath);\n            CreateFile(rootPath, \"b1\");\n            CreateFile(rootPath, \"b2\");\n\n            var d1Path = Path.Combine(rootPath, \"d1\");\n            Directory.CreateDirectory(d1Path);\n            CreateFile(d1Path, \"b1\");\n            CreateFile(d1Path, \"b2\");\n\n            var d2Path = Path.Combine(rootPath, \"d2\");\n            Directory.CreateDirectory(d2Path);\n            CreateFile(d2Path, \"b3\");\n            CreateFile(d2Path, \"b4\");\n\n            var d3Path = Path.Combine(d2Path, \"d3\");\n            Directory.CreateDirectory(d3Path);\n            CreateFile(d3Path, \"b5\");\n            CreateFile(d3Path, \"b6\");\n\n            var d4Path = Path.Combine(rootPath, \"d4\");\n            Directory.CreateDirectory(d4Path);\n            var d5Path = Path.Combine(d4Path, \"d5\");\n            Directory.CreateDirectory(d5Path);\n            CreateFile(d5Path, \"b7\");\n            return rootPath;\n        }\n\n        private async Task CreateNewDirectory(string path)\n        {\n            await FileUtils.DeleteDirectoryIfAny(path);\n            Directory.CreateDirectory(path);\n        }\n\n        private void CreateFile(string dir, string relPath)\n        {\n            var path = Path.Combine(dir, relPath);\n            // the file must contain something otherwise uploading to blob storage will fail\n            File.WriteAllText(path, path);\n        }\n\n        private string GetTestDirPath(string testName)\n        {\n            var path = Path.Combine(Path.GetTempPath(), nameof(BlobUtilsTest), testName);\n            if (!Directory.Exists(path))\n            {\n                Directory.CreateDirectory(path);\n            }\n            return path;\n        }\n    }\n}"
  },
  {
    "path": "test/AzureUtilsTest/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"AzureUtilsTest\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"AzureUtilsTest\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"2fe963bd-d826-4cc5-8a63-864cda212233\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/AzureUtilsTest/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net461\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net461\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net461\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net461\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net461\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net461\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net461\" />\n  <package id=\"xunit\" version=\"2.1.0\" targetFramework=\"net461\" />\n  <package id=\"xunit.abstractions\" version=\"2.0.0\" targetFramework=\"net461\" />\n  <package id=\"xunit.assert\" version=\"2.1.0\" targetFramework=\"net461\" />\n  <package id=\"xunit.core\" version=\"2.1.0\" targetFramework=\"net461\" />\n  <package id=\"xunit.extensibility.core\" version=\"2.1.0\" targetFramework=\"net461\" />\n  <package id=\"xunit.extensibility.execution\" version=\"2.1.0\" targetFramework=\"net461\" />\n</packages>"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Application/ApplicationConfigParserTest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Json;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Utils;\nusing Newtonsoft.Json.Serialization;\nusing Semver;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Application\n{\n    public class ApplicationConfigParserTest\n    {\n        [Fact]\n        public async Task TestParseApplicationConfig()\n        {\n            string path = Path.Combine(Directory.GetCurrentDirectory(), \"Data\\\\ApplicationConfigParser\\\\AppConfig.json\");\n            const string clusterId = \"clusterid1\";\n            const string instanceId = \"instanceid1\";\n            \n            AppIdentity identity = new AppIdentity(\"HelloApp\", new SemVersion(1,0,0));\n            Dictionary<string, string> properties = new Dictionary<string, string> {[\"NodeType\"] = \"PROD\"};\n            AppDeploymentConfig appDeploymentConfig = new AppDeploymentConfig(identity, new [] {clusterId}, properties);\n            ApplicationConfig appConfig = await new ApplicationConfigParser(new ApplicationConfigSymbolResolver(clusterId, instanceId),\n                new JsonSerializer(new DiagnosticsTraceWriter())).ParseFile(path, appDeploymentConfig);\n\n            Assert.Equal(identity, appConfig.Identity);\n            Assert.Equal(\"HelloApp.exe\", appConfig.ExeName);\n            Assert.Equal(\"HelloApp_1.0_instanceid1 foo bar=HelloApp_1.0_clusterid1 nodeType=PROD\", appConfig.ExeArgs);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Application/ApplicationConfigSymbolResolverTest.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Install;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Application\n{\n    public class ApplicationConfigSymbolResolverTest\n    {\n        [Fact]\n        public async Task TestResolve()\n        {\n            var resolver = new ApplicationConfigSymbolResolver(\"clusterId\", \"instanceId\", new Dictionary<string, string>() { {\"clusterPropKey\", \"clusterPropValue\"}});\n            var appInstallConfig = new AppInstallConfig(new AppIdentity(\"app\", \"1.0.0-test\"), new Dictionary<string, string> { {\"appPropKey\", \"appPropValue\"} });\n\n            Assert.Equal(\"clusterId\", await resolver.ResolveSymbol(appInstallConfig, \"ClusterId\"));\n            Assert.Equal(\"instanceId\", await resolver.ResolveSymbol(appInstallConfig, \"InstanceId\"));\n            Assert.Equal(\"app\", await resolver.ResolveSymbol(appInstallConfig, \"Id\"));\n            Assert.Equal(\"1.0.0-test\", await resolver.ResolveSymbol(appInstallConfig, \"Version\"));\n            Assert.Equal(\"1\", await resolver.ResolveSymbol(appInstallConfig, \"Version.Major\"));\n            Assert.Equal(\"0\", await resolver.ResolveSymbol(appInstallConfig, \"Version.Minor\"));\n            Assert.Equal(\"0\", await resolver.ResolveSymbol(appInstallConfig, \"Version.Build\"));\n            Assert.Equal(\"test\", await resolver.ResolveSymbol(appInstallConfig, \"Version.Prerelease\"));\n            Assert.Equal(\"clusterPropValue\", await resolver.ResolveSymbol(appInstallConfig, \"clusterPropKey\"));\n            Assert.Equal(\"appPropValue\", await resolver.ResolveSymbol(appInstallConfig, \"appPropKey\"));\n        }\n\n        [Fact]\n        public async Task TestThatAppPropertiesOverwritesClusterProperties()\n        {\n            var resolver = new ApplicationConfigSymbolResolver(\"clusterId\", \"instanceId\", new Dictionary<string, string>() { { \"propKey\", \"clusterPropValue\" } });\n            var appInstallConfig = new AppInstallConfig(new AppIdentity(\"app\", \"1.0.0-test\"), new Dictionary<string, string> { { \"propKey\", \"appPropValue\" } });\n\n            Assert.Equal(\"appPropValue\", await resolver.ResolveSymbol(appInstallConfig, \"propKey\"));\n        }\n    }\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Application/ApplicationPoolTest.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Install;\nusing Etg.Yams.Json;\nusing Etg.Yams.Process;\nusing Etg.Yams.Test.stubs;\nusing Etg.Yams.Test.Utils;\nusing Etg.Yams.Utils;\nusing Newtonsoft.Json.Serialization;\nusing Semver;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Application\n{\n    public class ApplicationPoolTestFixture\n    {\n        public string ApplicationsRootPath { get; private set; }\n        public IApplicationFactory ApplicationFactory { get; private set; }\n        private const string ClusterId = \"testClusterId\";\n        private const string InstanceId = \"testInstanceId\";\n\n        public ApplicationPoolTestFixture()\n        {\n            var dataRootPath = Path.Combine(Directory.GetCurrentDirectory(), \"Data\", \"ApplicationPool\");\n            var testDirPath = Path.Combine(Directory.GetCurrentDirectory(), \"ApplicationPoolTest\");\n            ApplicationsRootPath = Path.Combine(testDirPath, \"Applications\");\n\n            FileUtils.CopyDir(dataRootPath, ApplicationsRootPath, overwrite: true).Wait();\n\n            const string exeName = \"TestProcess.exe\";\n            string[] testAppsRelPath =\n            {\n                Path.Combine(\"test.myapp\", \"1.0.0\"),\n                Path.Combine(\"test.myapp\", \"1.0.1\"),\n            };\n\n            foreach (string testAppRelPath in testAppsRelPath)\n            {\n                TestUtils.CopyExe(exeName, Path.Combine(ApplicationsRootPath, testAppRelPath));\n            }\n\n            YamsConfig config = new YamsConfigBuilder(\"clusterId\", \"1\", \"instanceId\", \"C:\\\\\")\n                .SetUseShellExecute(false).SetApplicationRestartCount(0).Build();\n            ApplicationFactory =\n                new ConfigurableApplicationFactory(new ApplicationConfigParser(\n                    new ApplicationConfigSymbolResolver(ClusterId, InstanceId), new JsonSerializer(new DiagnosticsTraceWriter())),\n                    new ProcessFactory(config, new Os.System()), new ProcessStopper(0));\n        }\n    }\n\n    public class ApplicationPoolTest : IClassFixture<ApplicationPoolTestFixture>, IDisposable\n    {\n        private ApplicationPool _applicationPool;\n        private readonly IApplicationFactory _applicationFactory;\n        private readonly string _applicationsRootPath;\n\n        public ApplicationPoolTest(ApplicationPoolTestFixture fixture)\n        {\n            _applicationPool = new ApplicationPool();\n            _applicationFactory = fixture.ApplicationFactory;\n            _applicationsRootPath = fixture.ApplicationsRootPath;\n        }\n\n        public void Dispose()\n        {\n            _applicationPool?.Shutdown().Wait();\n        }\n\n        [Fact]\n        public async Task TestAddApplication()\n        {\n            AppIdentity appIdentity = new AppIdentity(\"test.myapp\", new SemVersion(1, 0, 0));\n            AppInstallConfig config = new AppInstallConfig(appIdentity);\n            await AddApplication(config);\n\n            Assert.NotNull(_applicationPool.GetApplication(appIdentity));\n            Assert.Equal(\"TestProcess.exe foo1 foo2 --AppName test.myapp --AppVersion 1.0.0\", GetOutput(appIdentity));\n        }\n\n        private async Task AddApplication(AppInstallConfig appInstallConfig)\n        {\n            IApplication application = await _applicationFactory.CreateApplication(appInstallConfig, \n                GetApplicationPath(appInstallConfig.AppIdentity));\n            await _applicationPool.AddApplication(application);\n        }\n\n        private string GetApplicationPath(AppIdentity appIdentity)\n        {\n            return Path.Combine(_applicationsRootPath, appIdentity.Id,\n                appIdentity.Version.ToString());\n        }\n\n        [Fact]\n        public async Task TestThatAddExistingApplicationThrowsAnException()\n        {\n            await Assert.ThrowsAsync<ArgumentException>(async () => {\n                AppIdentity appIdentity = new AppIdentity(\"test.myapp\", new SemVersion(1, 0, 0));\n                AppInstallConfig config = new AppInstallConfig(appIdentity);\n                await AddApplication(config);\n                await AddApplication(config);\n            });\n        }\n\n        [Fact]\n        public void TestThatGetApplicationReturnsNullIfApplicationDoesntExist()\n        {\n            AppIdentity appIdentity = new AppIdentity(\"test.myapp\", new SemVersion(1, 0, 0));\n            Assert.Null(_applicationPool.GetApplication(appIdentity));\n        }\n\n        [Fact]\n        public async Task TestRemoveApplication()\n        {\n            int startCallCount = 0;\n            int stopCallCount = 0;\n            AppIdentity appIdentity = new AppIdentity(\"test.myapp\", new SemVersion(1, 0, 0));\n            IApplication application = new StubIApplication()\n                .Start(() =>\n                {\n                    startCallCount++;\n                    return Task.FromResult(true);\n                })\n                .Stop(() =>\n                {\n                    stopCallCount++;\n                    return Task.FromResult(true);\n                })\n                .Identity_Get(() => appIdentity)\n                .Dispose(() => { });\n\n            _applicationPool = new ApplicationPool();\n\n            await _applicationPool.AddApplication(application);\n\n            Assert.True(_applicationPool.HasApplication(appIdentity));\n            Assert.Equal(1, startCallCount);\n            Assert.Equal(0, stopCallCount);\n\n            await _applicationPool.RemoveApplication(appIdentity);\n            Assert.Equal(1, stopCallCount);\n        }\n\n        [Fact]\n        public async Task TestRemoveApplicationThatThrowsWhenStopped()\n        {\n            AppIdentity appIdentity = new AppIdentity(\"test.myapp\", new SemVersion(1, 0, 0));\n            IApplication application = new StubIApplication()\n                .Start(() => Task.FromResult(true))\n                .Stop(() => throw new Exception(\"Exception thrown on Stop\"))\n                .Dispose(() => throw new Exception(\"Exception thrown on Dispose\"))\n                .Identity_Get(() => appIdentity);\n\n            _applicationPool = new ApplicationPool();\n\n            await _applicationPool.AddApplication(application);\n            Assert.True(_applicationPool.HasApplication(appIdentity));\n\n            await _applicationPool.RemoveApplication(appIdentity);\n            Assert.False(_applicationPool.HasApplication(appIdentity));\n        }\n\n        [Fact]\n        public async Task TestThatAnExceptionIsThrownIfApplicationFailsToStart()\n        {\n            await Assert.ThrowsAsync<Exception>(async () =>\n            {\n\t            IApplication application = new StubIApplication()\n\t\t            .Start(() => Task.FromResult(false))\n\t\t            .Identity_Get(() => new AppIdentity(\"test.myapp\", new SemVersion(1, 0, 0)));\n                await _applicationPool.AddApplication(application);\n            });\n        }\n\n        [Fact]\n        public async Task TestThatExitedApplicationsAreRemoved()\n        {\n            AppIdentity appIdentity = new AppIdentity(\"test.myapp\", new SemVersion(1, 0, 0));\n            ApplicationStub application = new ApplicationStub(appIdentity, \"path\");\n\n            await _applicationPool.AddApplication(application);\n            Assert.True(_applicationPool.HasApplication(appIdentity));\n\n            application.Fail();\n            Assert.False(_applicationPool.HasApplication(appIdentity));\n        }\n\n        [Fact]\n        public async Task TestThatRemoveNonExistingApplicationThrowsAnException()\n        {\n            await Assert.ThrowsAsync<ArgumentException>(async () =>\n            {\n                AppIdentity appIdentity = new AppIdentity(\"test.myapp\", new SemVersion(1, 0, 0));\n                await _applicationPool.RemoveApplication(appIdentity);\n            });\n        }\n\n        private string GetOutput(AppIdentity appIdentity)\n        {\n            return TestUtils.GetTestApplicationOutput(_applicationsRootPath, appIdentity, \"TestProcess\");\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Application/ApplicationTest.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Process;\nusing Etg.Yams.Test.stubs;\nusing Semver;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Application\n{\n    public class ApplicationTestFixture : IDisposable\n    {\n        public const string ExeName = \"exeName\";\n        public ApplicationConfig AppConfig { get; set; }\n\t    public const string AppPath = \"path\";\n        public const string TestExeArgs = \"arg1, arg2\";\n\n        public ApplicationTestFixture()\n        {\n\t        var appIdentity = new AppIdentity(\"id\", new SemVersion(1,0,0));\n\t        AppConfig = new ApplicationConfig(appIdentity, ExeName, TestExeArgs);\n        }\n\n\t    public void Dispose() { }\n    }\n\n    public class ApplicationTest : IClassFixture<ApplicationTestFixture>\n    {\n        private readonly ApplicationConfig _appConfig;\n\n        public ApplicationTest(ApplicationTestFixture fixture)\n        {\n            _appConfig = fixture.AppConfig;\n        }\n\n        [Fact]\n        public async Task TestStartProcessHappyPath()\n        {\n            int startCallCount = 0;\n            int stopCallCount = 0;\n\n            string exePath = \"\";\n            string exeArgs = \"\";\n\n            IProcess process = new StubIProcess()\n                .Start(args =>\n                {\n                    exeArgs = args;\n                    startCallCount++;\n                    return Task.FromResult(true);\n                }\n            );\n\n            IProcessFactory processFactory = new StubIProcessFactory()\n                .CreateProcess((identity, path, initialization, health, shutdown) =>\n                {\n                    exePath = path;\n                    return process;\n                });\n\n            IProcessStopper processStopper = new StubIProcessStopper()\n                .StopProcess(p =>\n                {\n                    ++stopCallCount;\n                    return Task.FromResult(true);\n                }\n            );\n\n            ConfigurableApplication application = new ConfigurableApplication(\n\t\t\t\tApplicationTestFixture.AppPath, _appConfig, processFactory, processStopper);\n            await application.Start();\n\n            Assert.Equal(1, startCallCount);\n            Assert.Equal(0, stopCallCount);\n            Assert.Equal(ApplicationTestFixture.TestExeArgs, exeArgs);\n            Assert.Equal(Path.Combine(ApplicationTestFixture.AppPath, ApplicationTestFixture.ExeName), exePath);\n        }\n\n        [Fact]\n        public async Task TestThatStartFailsIfProcessFailsToStart()\n        {\n            IProcess process = new StubIProcess()\n                .Start(args => { throw new Exception(\"Process failed to start\"); });\n\n            IProcessFactory processFactory = new StubIProcessFactory()\n                .CreateProcess((identity, path, initialization, health, shutdown) => process);\n\n            IProcessStopper processStopper = new StubIProcessStopper();\n\n            ConfigurableApplication application = new ConfigurableApplication(\n\t\t\t\tApplicationTestFixture.AppPath, _appConfig, processFactory, processStopper);\n            Assert.False(await application.Start());\n        }\n\n        [Fact]\n        public async Task TestThatStopStopsTheProcess()\n        {\n            int stopCallCount = 0;\n\t        IProcess process = new StubIProcess().Start(args => Task.FromResult(true));\n\n            IProcessStopper processStopper = new StubIProcessStopper()\n                .StopProcess(p =>\n                {\n                    ++stopCallCount;\n                    return Task.FromResult(true);\n                }\n            );\n\n            IProcessFactory processFactory = new StubIProcessFactory()\n                .CreateProcess((identity, path, initialization, health, shutdown) => process);\n            ConfigurableApplication application = new ConfigurableApplication(\n\t\t\t\tApplicationTestFixture.AppPath, _appConfig, processFactory, processStopper);\n            await application.Start();\n            await application.Stop();\n\n            Assert.Equal(1, stopCallCount);\n        }\n\n        [Fact]\n        public async Task TestThatExitedEventIsEmittedWhenProcessFails()\n        {\n            ProcessStub process = new ProcessStub(\"\");\n\t        IProcessFactory processFactory = new StubIProcessFactory()\n\t\t        .CreateProcess((identity, path, initialization, health, shutdown) => process);\n\n            ConfigurableApplication application = new ConfigurableApplication(ApplicationTestFixture.AppPath, _appConfig, processFactory, new StubIProcessStopper());\n            ApplicationExitedArgs appExitedArgs = null;\n            int exitedEventCount = 0;\n            application.Exited += (sender, args) =>\n            {\n                appExitedArgs = args;\n                ++exitedEventCount;\n            };\n            await application.Start();\n            process.RaiseExitedEvent();\n\n            Assert.Equal(1, exitedEventCount);\n            Assert.Equal(_appConfig.Identity, appExitedArgs.AppIdentity);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Client/YamsProcessArgsParserTest.cs",
    "content": "using Etg.Yams.Client;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Client\n{\n    public class YamsProcessArgsParserTest\n    {\n        [Fact]\n        public void TestParseOneArg()\n        {\n            var parser = new ProcessArgsParser();\n            var options = parser.ParseArgs(new [] { \"--InitializationPipeName\", \"Foo\" });\n            Assert.Equal(\"Foo\", options.InitializationPipeName);\n            Assert.Null(options.HealthPipeName);\n            Assert.Null(options.ExitPipeName);\n        }\n\n        [Fact]\n        public void TestParseTwoArgs()\n        {\n            var parser = new ProcessArgsParser();\n            var options = parser.ParseArgs(new[] { \"--InitializationPipeName\", \"Foo\", \"--HealthPipeName\", \"Bar\" });\n            Assert.Equal(\"Foo\", options.InitializationPipeName);\n            Assert.Equal(\"Bar\", options.HealthPipeName);\n            Assert.Null(options.ExitPipeName);\n        }\n\n        [Fact]\n        public void TestParseAllArgs()\n        {\n            var parser = new ProcessArgsParser();\n            var options = parser.ParseArgs(new[] { \"--InitializationPipeName\", \"Foo\", \"--HealthPipeName\", \"Bar\", \"--ExitPipeName\", \"abc\" });\n            Assert.Equal(\"Foo\", options.InitializationPipeName);\n            Assert.Equal(\"Bar\", options.HealthPipeName);\n            Assert.Equal(\"abc\", options.ExitPipeName);\n        }\n\n        [Fact]\n        public void TestThatParseArgsIgnoresAdditionalArgs()\n        {\n            var parser = new ProcessArgsParser();\n            var options = parser.ParseArgs(new[] { \"blabla\", \"--InitializationPipeName\", \"Foo\", \"--HealthPipeName\", \"Bar\", \"--ExitPipeName\", \"abc\", \"--Other\", \"Bar\", \"--AppName\", \"App\", \"--AppVersion\", \"1.2.3-alpha4\" });\n            Assert.Equal(\"App\", options.AppName);\n            Assert.Equal(\"1.2.3-alpha4\", options.AppVersion);\n            Assert.Equal(\"Foo\", options.InitializationPipeName);\n            Assert.Equal(\"Bar\", options.HealthPipeName);\n            Assert.Equal(\"abc\", options.ExitPipeName);\n        }\n\n        [Fact]\n        public void TestParseAppNameArg()\n        {\n            var parser = new ProcessArgsParser();\n            var options = parser.ParseArgs(new[] { \"--AppName\", \"Foo\" });\n            Assert.Equal(\"Foo\", options.AppName);\n            Assert.Null(options.AppVersion);\n        }\n\n        [Fact]\n        public void TestParseAppVersionArg()\n        {\n            var parser = new ProcessArgsParser();\n            var options = parser.ParseArgs(new[] { \"--AppVersion\", \"1.2.3-alpha4\" });\n            Assert.Equal(\"1.2.3-alpha4\", options.AppVersion);\n            Assert.Null(options.AppName);\n        }\n\n        [Fact]\n        public void TestThatParseEmptyArgsIsOk()\n        {\n            var parser = new ProcessArgsParser();\n            var options = parser.ParseArgs(new string[] {});\n            Assert.Null(options.AppName);\n            Assert.Null(options.AppVersion);\n            Assert.Null(options.InitializationPipeName);\n            Assert.Null(options.HealthPipeName);\n            Assert.Null(options.ExitPipeName);\n        }\n    }\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/ApplicationConfigParser/AppConfig.json",
    "content": "﻿{ \n    \"ExeName\": \"HelloApp.exe\", \n    \"ExeArgs\": \"${Id}_${Version.Major}.${Version.Minor}_${InstanceId} foo bar=${Id}_${Version.Major}.${Version.Minor}_${ClusterId} nodeType=${NodeType}\"\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/ApplicationPool/test.myapp/1.0.0/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"TestProcess.exe\",\n    \"ExeArgs\": \"foo1 foo2\" \n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/ApplicationPool/test.myapp/1.0.1/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"TestProcess.exe\",\n    \"ExeArgs\": \"foo3 foo4\" \n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/DeploymentConfig/DeploymentConfig.json",
    "content": "﻿{\n  \"Applications\": [\n    {\n      \"Id\": \"app1\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ],\n      \"Properties\": \n      {\n      }\n    },\n    {\n      \"Id\": \"app1\",\n      \"Version\": \"1.0.1\",\n      \"TargetClusters\": [ \"clusterId1\", \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"app2\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ],\n      \"Properties\": {\n        \"NodeType\": \"PROD\"\n      }\n    },\n    {\n      \"Id\": \"app3\",\n      \"Version\": \"2.0.0-beta\",\n      \"TargetClusters\": [ \"clusterId3\" ]\n    }\n  ]\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/DeploymentConfig.json",
    "content": "﻿{\n  \"Applications\": [\n    {\n      \"Id\": \"test.app1\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ]\n    },\n    {\n      \"Id\": \"test.app2\",\n      \"Version\": \"1.1.0\",\n      \"TargetClusters\": [ \"clusterId1\", \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"test.app2\",\n      \"Version\": \"2.0.0-beta\",\n      \"TargetClusters\": [ \"clusterId1\", \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"test.app3\",\n      \"Version\": \"1.1.0\",\n      \"TargetClusters\": [ \"clusterId1\", \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"test.app4\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"test.app5\", // this app has no associated binaries\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ]\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/DeploymentConfigFullIpcApp.json",
    "content": "﻿{\n  \"Applications\": [\n    {\n      \"Id\": \"FullIpcApp\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ]\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/DeploymentConfigGracefulShutdownApp.json",
    "content": "﻿{\n  \"Applications\": [\n    {\n      \"Id\": \"GracefulShutdownApp\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ]\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/DeploymentConfigHeartBeatApp.json",
    "content": "﻿{\n  \"Applications\": [\n    {\n      \"Id\": \"HeartBeatApp\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ]\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/DeploymentConfigMonitorInitApp.json",
    "content": "﻿{\n  \"Applications\": [\n    {\n      \"Id\": \"MonitorInitApp\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ]\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/DeploymentConfigNoApps.json",
    "content": "﻿{\n  \"Applications\": [\n  ]\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/DeploymentConfigUpdate.json",
    "content": "﻿{\n  \"Applications\": [\n    {\n      \"Id\": \"test.app1\",\n      \"Version\": \"1.0.1\",\n      \"targetClusters\": [ \"clusterId1\" ]\n    },\n    {\n      \"Id\": \"test.app2\",\n      \"Version\": \"1.1.0\",\n      \"targetClusters\": [ \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"test.app2\",\n      \"Version\": \"2.0.0-beta\",\n      \"targetClusters\": [ \"clusterId1\", \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"test.app3\",\n      \"Version\": \"1.0.0\",\n      \"targetClusters\": [ \"clusterId1\", \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"test.app3\",\n      \"Version\": \"1.1.0\",\n      \"targetClusters\": [ \"clusterId1\", \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"test.app4\",\n      \"Version\": \"1.0.0\",\n      \"targetClusters\": [ \"clusterId1\" ]\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/DeploymentConfigWithProperties.json",
    "content": "﻿{\n  \"Applications\": [\n    {\n      \"Id\": \"test.app1\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ],\n      \"Properties\": {\n        \"NodeType\": \"Test\",\n        \"Region\":  \"East\"\n      }\n    },\n    {\n      \"Id\": \"test.app2\",\n      \"Version\": \"1.1.0\",\n      \"TargetClusters\": [ \"clusterId1\", \"clusterId2\" ],\n      \"Properties\": {\n        \"NodeType\": \"Test\",\n        \"Region\": \"West\"\n      }\n    },\n    {\n      \"Id\": \"test.app2\",\n      \"Version\": \"2.0.0-beta\",\n      \"TargetClusters\": [ \"clusterId1\", \"clusterId2\" ],\n      \"Properties\": {\n        \"NodeType\": \"Test\"\n      }\n    },\n    {\n      \"Id\": \"test.app3\",\n      \"Version\": \"1.1.0\",\n      \"TargetClusters\": [ \"clusterId1\", \"clusterId2\" ],\n      \"Properties\": {\n        \"NodeType\": \"Prod\",\n        \"Region\": \"East\"\n      }\n    },\n    {\n      \"Id\": \"test.app4\",\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId2\" ]\n    },\n    {\n      \"Id\": \"test.app5\", // this app has no associated binaries\n      \"Version\": \"1.0.0\",\n      \"TargetClusters\": [ \"clusterId1\" ]\n    }\n  ]\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/FullIpcApp/1.0.0/AppConfig.json",
    "content": "﻿{\n  \"ExeName\": \"FullIpcProcess.exe\",\n  \"ExeArgs\": \"foo1 foo2\",\n  \"MonitorInitialization\": true,\n  \"MonitorHealth\": true,\n  \"GracefulShutdown\":  true\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/GracefulShutdownApp/1.0.0/AppConfig.json",
    "content": "﻿{\n  \"ExeName\": \"GracefullShutdownProcess.exe\",\n  \"ExeArgs\": \"foo1 foo2 4\",\n  \"GracefulShutdown\": true\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/HeartBeatApp/1.0.0/AppConfig.json",
    "content": "﻿{\n  \"ExeName\": \"HeartBeatProcess.exe\",\n  \"ExeArgs\": \"foo1 foo2 2\",\n  \"MonitorHealth\":  true\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/MonitorInitApp/1.0.0/AppConfig.json",
    "content": "﻿{\n  \"ExeName\": \"MonitorInitProcess.exe\",\n  \"ExeArgs\": \"foo1 foo2 2\",\n  \"MonitorInitialization\": true\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/test.app1/1.0.0/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"TestProcess.exe\",\n    \"ExeArgs\": \"foo1 foo2\" \n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/test.app1/1.0.1/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"TestProcess.exe\",\n    \"ExeArgs\": \"foo1 foo2\" \n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/test.app2/1.1.0/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"TestProcess.exe\",\n    \"ExeArgs\": \"foo1 foo2\" \n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/test.app2/2.0.0-beta/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"TestProcess.exe\",\n    \"ExeArgs\": \"foo1 foo2\" \n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/test.app3/1.0.0/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"TestProcess.exe\",\n    \"ExeArgs\": \"foo1 foo2\" \n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/test.app3/1.1.0/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"TestProcess.exe\",\n    \"ExeArgs\": \"foo1 foo2\" \n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Data/EndToEndTest/test.app4/1.0.0/AppConfig.json",
    "content": "﻿{\n    \"ExeName\": \"TestProcess.exe\",\n    \"ExeArgs\": \"foo1 foo2\" \n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/EndToEndTest.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Test.Storage;\nusing Etg.Yams.Test.Utils;\nusing Etg.Yams.Update;\nusing Etg.Yams.Utils;\nusing Xunit;\nusing Autofac;\nusing Etg.Yams.Json;\nusing Etg.Yams.Storage.Config;\nusing Newtonsoft.Json.Serialization;\nusing Semver;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Install;\nusing System.Collections.Generic;\nusing Etg.Yams.Storage.Status;\n\nnamespace Etg.Yams.Test\n{\n    public class EndToEndTest : IDisposable\n    {\n        private readonly string _dataRootPath;\n        private readonly string _testDirPath;\n        private readonly string _applicationsInstallPath;\n        private readonly string _deploymentDirPath;\n        private IYamsService _yamsService;\n        private YamsDiModule _yamsDiModule;\n        private LocalDeploymentRepository _deploymentRepository;\n\n        public EndToEndTest()\n        {\n            _dataRootPath = Path.Combine(Directory.GetCurrentDirectory(), \"Data\", \"EndToEndTest\");\n            _testDirPath = Path.Combine(Directory.GetCurrentDirectory(), \"EndToEndTest\");\n            _deploymentDirPath = Path.Combine(_testDirPath, \"Deployments\");\n            _applicationsInstallPath = Path.Combine(_testDirPath, \"applications\");\n\n            FileUtils.CopyDir(_dataRootPath, _deploymentDirPath, overwrite: true).Wait();\n\n            CopyTestProcessExeToTestApps();\n        }\n\n        private void InitializeYamsService(YamsConfig yamsConfig)\n        {\n            ContainerBuilder builder = InitializeContainerBuilder(yamsConfig);\n            InitializeYamsService(builder.Build());\n        }\n\n        private void InitializeYamsService(IContainer container)\n        {\n            _yamsDiModule = new YamsDiModule(container);\n            _yamsService = _yamsDiModule.YamsService;\n        }\n\n        private ContainerBuilder InitializeContainerBuilder(YamsConfig yamsConfig)\n        {\n            IUpdateSessionManager updateSessionManager = new StubIUpdateSessionManager()\n                .TryStartUpdateSession(() => Task.FromResult(true))\n                .EndUpdateSession(() => Task.CompletedTask);\n\n            JsonSerializer jsonSerializer = new JsonSerializer(new DiagnosticsTraceWriter());\n            _deploymentRepository = new LocalDeploymentRepository(_deploymentDirPath,\n                new JsonDeploymentConfigSerializer(jsonSerializer),\n                new JsonDeploymentStatusSerializer(jsonSerializer));\n            \n            return YamsDiModule.RegisterTypes(yamsConfig, _deploymentRepository, _deploymentRepository, updateSessionManager);\n        }\n\n        private void CopyTestProcessExeToTestApps()\n        {\n            // The exe will be created at compile time. The code below copies the exe to each\n            // of the test apps used for testing.\n            const string exeName = \"TestProcess.exe\";\n            string[] testAppsRelPath =\n            {\n                Path.Combine(\"test.app1\", \"1.0.0\"),\n                Path.Combine(\"test.app1\", \"1.0.1\"),\n                Path.Combine(\"test.app2\", \"1.1.0\"),\n                Path.Combine(\"test.app2\", \"2.0.0-beta\"),\n                Path.Combine(\"test.app3\", \"1.0.0\"),\n                Path.Combine(\"test.app3\", \"1.1.0\"),\n                Path.Combine(\"test.app4\", \"1.0.0\"),\n            };\n\n            foreach (string testAppRelPath in testAppsRelPath)\n            {\n                TestUtils.CopyExe(exeName, Path.Combine(_deploymentDirPath, testAppRelPath));\n            }\n        }\n\n        public void Dispose()\n        {\n            _yamsService.Stop().Wait();\n            DeleteDirectory(_testDirPath);\n        }\n\n        /// <summary>\n        /// This test replaces the content DeploymentConfig.json file with DeploymentConfigUpdate.json file.\n        /// Several updates are involved:\n        /// - test.app1.1.0.0 is removed\n        /// - test.app1.1.0.1 is added\n        /// - test.app2.1.1.0 deployment id is changed (i.e. the app is removed)\n        /// - test.app2.2.0.0-beta is still there\n        /// - test.app3.1.0.0 is added\n        /// - test.app3.1.1.0 is still there\n        /// - test.app4.1.0.0 deployment id now matches the cluster deployment id (i.e. the app is added)\n        /// </summary>\n        [Fact]\n        public async Task TestMultipleUpdates()\n        {\n            const string ClusterId = \"clusterId1\";\n            const string InstanceId = \"instanceId\";\n            var yamsConfig = new YamsConfigBuilder(ClusterId, \"1\", InstanceId,\n                _applicationsInstallPath).SetUseShellExecute(false).Build();\n\n            InitializeYamsService(yamsConfig);\n\n            IApplicationUpdateManager applicationUpdateManager = _yamsDiModule.Container.Resolve<IApplicationUpdateManager>();\n            await applicationUpdateManager.CheckForUpdates();\n\n            AssertThatApplicationIsRunning(new AppIdentity(\"test.app1\", new SemVersion(1, 0, 0)), \"TestProcess\");\n            AssertThatApplicationIsRunning(new AppIdentity(\"test.app2\", new SemVersion(1, 1, 0)), \"TestProcess\");\n            AssertThatApplicationIsRunning(new AppIdentity(\"test.app2\", new SemVersion(2, 0, 0, \"beta\")), \"TestProcess\");\n            AssertThatApplicationIsRunning(new AppIdentity(\"test.app3\", new SemVersion(1, 1, 0)), \"TestProcess\");\n\n            UploadDeploymentConfig(\"DeploymentConfigUpdate.json\");\n\n            await applicationUpdateManager.CheckForUpdates();\n\n            AssertThatApplicationIsNotRunning(new AppIdentity(\"test.app1\", new SemVersion(1, 0, 0)));\n            AssertThatApplicationIsNotRunning(new AppIdentity(\"test.app2\", new SemVersion(1, 1, 0)));\n\n            AppIdentity app1v101 = new AppIdentity(\"test.app1\", new SemVersion(1, 0, 1));\n            AppIdentity app2v200beta = new AppIdentity(\"test.app2\", new SemVersion(2, 0, 0, \"beta\"));\n            AppIdentity app3v100 = new AppIdentity(\"test.app3\", new SemVersion(1, 0, 0));\n            AppIdentity app3v110 = new AppIdentity(\"test.app3\", new SemVersion(1, 1, 0));\n            AppIdentity app4v100 = new AppIdentity(\"test.app4\", new SemVersion(1, 0, 0));\n\n            AssertThatApplicationIsRunning(app1v101, \"TestProcess\");\n            AssertThatApplicationIsRunning(app2v200beta, \"TestProcess\");\n            AssertThatApplicationIsRunning(app3v100, \"TestProcess\");\n            AssertThatApplicationIsRunning(app3v110, \"TestProcess\");\n            AssertThatApplicationIsRunning(app4v100, \"TestProcess\");\n\n            AssertThatNumberOfApplicationsRunningIs(5);\n\n            InstanceDeploymentStatus deploymentStatus = await _deploymentRepository.FetchInstanceDeploymentStatus(ClusterId, InstanceId);\n            VerifyThatDeploymentStatusHasBeenUpdated(deploymentStatus, app1v101, ClusterId, InstanceId);\n            VerifyThatDeploymentStatusHasBeenUpdated(deploymentStatus, app2v200beta, ClusterId, InstanceId);\n            VerifyThatDeploymentStatusHasBeenUpdated(deploymentStatus, app3v100, ClusterId, InstanceId);\n            VerifyThatDeploymentStatusHasBeenUpdated(deploymentStatus, app3v110, ClusterId, InstanceId);\n            VerifyThatDeploymentStatusHasBeenUpdated(deploymentStatus, app4v100, ClusterId, InstanceId);\n        }\n\n        private void VerifyThatDeploymentStatusHasBeenUpdated(InstanceDeploymentStatus instanceDeploymentStatus, \n            AppIdentity appIdentity, string clusterId, string instanceId)\n        {\n            var appDeploymentStatus = instanceDeploymentStatus.GetAppDeploymentStatus(appIdentity);\n            Assert.NotNull(appDeploymentStatus);\n            Assert.Equal(appIdentity, appDeploymentStatus.AppIdentity);\n            Assert.Equal(clusterId, appDeploymentStatus.ClusterId);\n            Assert.Equal(instanceId, appDeploymentStatus.InstanceId);\n            Assert.NotNull(appDeploymentStatus.UtcTimeStamp);\n        }\n\n        private void UploadDeploymentConfig(string deploymentConfigFileName)\n        {\n            File.Copy(Path.Combine(_dataRootPath, deploymentConfigFileName), Path.Combine(_deploymentDirPath,\n                \"DeploymentConfig.json\"), overwrite: true);\n        }\n\n        [Fact]\n        public async Task TestThatClusterPropertiesAreUsedToMatchDeployments()\n        {\n            UploadDeploymentConfig(\"DeploymentConfigWithProperties.json\");\n            var yamsConfig = new YamsConfigBuilder(\"clusterId1\", \"1\", \"instanceId\",\n                _applicationsInstallPath).SetUseShellExecute(false)\n                .AddClusterProperty(\"NodeType\", \"Test\")\n                .AddClusterProperty(\"Region\", \"East\").Build();\n\n            var installedApps = new List<AppInstallConfig>();\n            var applicationInstallerStub = new StubIApplicationInstaller().Install(\n                (config) => \n                {\n                    installedApps.Add(config);\n                    return Task.CompletedTask;\n                });\n\n            ContainerBuilder builder = InitializeContainerBuilder(yamsConfig);\n            builder.RegisterInstance<IApplicationInstaller>(applicationInstallerStub);\n            InitializeYamsService(builder.Build());\n\n            IApplicationUpdateManager applicationUpdateManager = _yamsDiModule.Container.Resolve<IApplicationUpdateManager>();\n            await applicationUpdateManager.CheckForUpdates();\n            \n            Assert.Equal(2, installedApps.Count);\n            Assert.True(installedApps.Any(config => config.AppIdentity == new AppIdentity(\"test.app1\", \"1.0.0\")));\n            Assert.True(installedApps.Any(config => config.AppIdentity == new AppIdentity(\"test.app2\", \"2.0.0-beta\")));\n\n            AppInstallConfig appInstallConfig = installedApps.Find(config => config.AppIdentity.Id == \"test.app1\");\n            Assert.Equal(new AppIdentity(\"test.app1\", new SemVersion(1, 0, 0)), appInstallConfig.AppIdentity);\n            Assert.True(appInstallConfig.Properties.ContainsKey(\"NodeType\"));\n            Assert.Equal(\"Test\", appInstallConfig.Properties[\"NodeType\"]);\n            Assert.True(appInstallConfig.Properties.ContainsKey(\"Region\"));\n            Assert.Equal(\"East\", appInstallConfig.Properties[\"Region\"]);\n        }\n\n        [Fact]\n        public async Task TestApplicationWithHeartBeat()\n        {\n            await RunHeartBeatTest(TimeSpan.FromSeconds(3));\n        }\n\n        /// <summary>\n        /// The current behaviour is to not terminate the app if it has slow (or no) heart beat but to only log errors.\n        /// </summary>\n        /// <returns></returns>\n        [Fact]\n        public async Task TestApplicationWithHeartBeatTimeout()\n        {\n            await RunHeartBeatTest(TimeSpan.FromSeconds(1));\n        }\n\n        private async Task RunHeartBeatTest(TimeSpan heartBeatTimeout)\n        {\n            await CopyAppBinariesToAppDeploymentDir(\"HeartBeatApp\", \"HeartBeatProcess\", \"1.0.0\");\n            UploadDeploymentConfig(\"DeploymentConfigHeartBeatApp.json\");\n\n            var yamsConfig = new YamsConfigBuilder(\"clusterId1\", \"1\", \"instanceId\",\n                    _applicationsInstallPath)\n                .SetAppHeartBeatTimeout(heartBeatTimeout)\n                .SetUseShellExecute(false).Build();\n\n            InitializeYamsService(yamsConfig);\n\n            IApplicationUpdateManager applicationUpdateManager = _yamsDiModule.Container.Resolve<IApplicationUpdateManager>();\n            await applicationUpdateManager.CheckForUpdates();\n\n            AssertThatApplicationIsRunning(new AppIdentity(\"HeartBeatApp\", new SemVersion(1, 0, 0)));\n            // wait for a bit to make sure heart beat messages are not failing\n            await Task.Delay(1000);\n            AssertThatApplicationIsRunning(new AppIdentity(\"HeartBeatApp\", new SemVersion(1, 0, 0)));\n        }\n\n        [Fact]\n        public async Task TestApplicationWithMonitoredInitialization()\n        {\n            await CopyAppBinariesToAppDeploymentDir(\"MonitorInitApp\", \"MonitorInitProcess\", \"1.0.0\");\n            UploadDeploymentConfig(\"DeploymentConfigMonitorInitApp.json\");\n\n            var yamsConfig = new YamsConfigBuilder(\"clusterId1\", \"1\", \"instanceId\",\n                _applicationsInstallPath).SetAppInitTimeout(TimeSpan.FromSeconds(10))\n                .SetUseShellExecute(false).Build();\n\n            InitializeYamsService(yamsConfig);\n\n            IApplicationUpdateManager applicationUpdateManager = _yamsDiModule.Container.Resolve<IApplicationUpdateManager>();\n            await applicationUpdateManager.CheckForUpdates();\n\n            AssertThatApplicationIsRunning(new AppIdentity(\"MonitorInitApp\", new SemVersion(1, 0, 0)));\n        }\n\n        [Fact]\n        public async Task TestApplicationWithGracefulShutdown()\n        {\n            await RunGracefulShutdownTest(TimeSpan.FromSeconds(10));\n        }\n\n        [Fact]\n        public async Task TestApplicationWithGracefulShutdownTimeout()\n        {\n            await RunGracefulShutdownTest(TimeSpan.FromSeconds(1));\n        }\n\n        private async Task RunGracefulShutdownTest(TimeSpan gracefulShutdownTimeout)\n        {\n            await CopyAppBinariesToAppDeploymentDir(\"GracefulShutdownApp\", \"GracefullShutdownProcess\", \"1.0.0\");\n            UploadDeploymentConfig(\"DeploymentConfigGracefulShutdownApp.json\");\n\n            var yamsConfig = new YamsConfigBuilder(\"clusterId1\", \"1\", \"instanceId\",\n                    _applicationsInstallPath).SetAppGracefulShutdownTimeout(gracefulShutdownTimeout)\n                .SetUseShellExecute(false).Build();\n\n            InitializeYamsService(yamsConfig);\n\n            IApplicationUpdateManager applicationUpdateManager = _yamsDiModule.Container.Resolve<IApplicationUpdateManager>();\n            await applicationUpdateManager.CheckForUpdates();\n            AssertThatApplicationIsRunning(new AppIdentity(\"GracefulShutdownApp\", new SemVersion(1, 0, 0)));\n\n            UploadDeploymentConfig(\"DeploymentConfigNoApps.json\");\n            await applicationUpdateManager.CheckForUpdates();\n            AssertThatApplicationIsNotRunning(new AppIdentity(\"GracefulShutdownApp\", new SemVersion(1, 0, 0)));\n        }\n\n        [Fact]\n        public async Task TestFullIpcApp()\n        {\n            await CopyAppBinariesToAppDeploymentDir(\"FullIpcApp\", \"FullIpcProcess\", \"1.0.0\");\n            UploadDeploymentConfig(\"DeploymentConfigFullIpcApp.json\");\n\n            var yamsConfig = new YamsConfigBuilder(\"clusterId1\", \"1\", \"instanceId\",\n                    _applicationsInstallPath).SetUseShellExecute(false).Build();\n\n            InitializeYamsService(yamsConfig);\n\n            IApplicationUpdateManager applicationUpdateManager = _yamsDiModule.Container.Resolve<IApplicationUpdateManager>();\n            await applicationUpdateManager.CheckForUpdates();\n            AssertThatApplicationIsRunning(new AppIdentity(\"FullIpcApp\", new SemVersion(1, 0, 0)));\n\n            await Task.Delay(5000);\n\n            UploadDeploymentConfig(\"DeploymentConfigNoApps.json\");\n            await applicationUpdateManager.CheckForUpdates();\n            AssertThatApplicationIsNotRunning(new AppIdentity(\"FullIpcApp\", new SemVersion(1, 0, 0)));\n        }\n\n        public void AssertThatApplicationIsRunning(AppIdentity appIdentity, string exeName = \"\")\n        {\n            if (String.IsNullOrEmpty(exeName))\n            {\n                exeName = appIdentity.Id;\n            }\n            IApplicationPool applicationPool = _yamsDiModule.Container.Resolve<IApplicationPool>();\n            Assert.True(applicationPool.HasApplication(appIdentity), $\"App {appIdentity} should be running!\");\n            string processOutput = TestUtils.GetTestApplicationOutput(_applicationsInstallPath, appIdentity, exeName);\n            Assert.True(processOutput.StartsWith($\"{exeName}.exe foo1 foo2\"));\n        }\n\n        private async Task CopyAppBinariesToAppDeploymentDir(string appName, string processName, string version)\n        {\n            await FileUtils.CopyDir(\n                srcPath: Path.Combine(Directory.GetCurrentDirectory(), \"Data\", processName),\n                destPath: Path.Combine(Directory.GetCurrentDirectory(), \"EndToEndTest\", \"Deployments\", appName, version),\n                overwrite: true);\n        }\n\n        public void AssertThatApplicationIsNotRunning(AppIdentity appIdentity)\n        {\n            IApplicationPool applicationPool = _yamsDiModule.Container.Resolve<IApplicationPool>();\n            Assert.False(applicationPool.HasApplication(appIdentity), $\"App {appIdentity} should not be running!\");\n            Assert.False(Directory.Exists(Path.Combine(_applicationsInstallPath, ApplicationUtils.GetApplicationRelativePath(appIdentity))));\n        }\n\n        public void AssertThatNumberOfApplicationsRunningIs(int count)\n        {\n            IApplicationPool applicationPool = _yamsDiModule.Container.Resolve<IApplicationPool>();\n            Assert.Equal(applicationPool.Applications.Count(), count);\n        }\n\n        private static void DeleteDirectory(string path)\n        {\n            if (Directory.Exists(path))\n            {\n                Directory.Delete(path, recursive: true);\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Etg.Yams.Core.Test.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"..\\..\\packages\\xunit.runner.visualstudio.2.1.0\\build\\net20\\xunit.runner.visualstudio.props\" Condition=\"Exists('..\\..\\packages\\xunit.runner.visualstudio.2.1.0\\build\\net20\\xunit.runner.visualstudio.props')\" />\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{98B0AE89-5D42-4366-9C0E-9392737E36AC}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.Test</RootNamespace>\n    <AssemblyName>Etg.Yams.Core.Test</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <NuGetPackageImportStamp>\n    </NuGetPackageImportStamp>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\CommandLineParser.1.9.71\\lib\\net45\\CommandLine.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.7.0\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.7.0\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.7.0\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.QualityTools.Testing.Fakes, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL\">\n      <SpecificVersion>False</SpecificVersion>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.7.0\\lib\\net40\\System.Spatial.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n    <Reference Include=\"xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.abstractions.2.0.0\\lib\\net35\\xunit.abstractions.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.assert, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.assert.2.1.0\\lib\\dotnet\\xunit.assert.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.core, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.core.2.1.0\\lib\\dotnet\\xunit.core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.execution.desktop, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.execution.2.1.0\\lib\\net45\\xunit.execution.desktop.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Application\\ApplicationConfigParserTest.cs\" />\n    <Compile Include=\"Application\\ApplicationConfigSymbolResolverTest.cs\" />\n    <Compile Include=\"Application\\ApplicationPoolTest.cs\" />\n    <Compile Include=\"Application\\ApplicationTest.cs\" />\n    <Compile Include=\"Client\\YamsProcessArgsParserTest.cs\" />\n    <Compile Include=\"EndToEndTest.cs\" />\n    <Compile Include=\"Install\\ApplicationInstallerTest.cs\" />\n    <Compile Include=\"Process\\GracefulShutdownProcessDecoratorTest.cs\" />\n    <Compile Include=\"Process\\ProcessStopperTest.cs\" />\n    <Compile Include=\"Process\\ProcessTest.cs\" />\n    <Compile Include=\"Process\\SelfRestartingProcessTest.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Storage\\DeploymentConfigTest.cs\" />\n    <Compile Include=\"Storage\\LocalDeploymentRepository.cs\" />\n    <Compile Include=\"Stubs\\ApplicationFactoryStub.cs\" />\n    <Compile Include=\"Stubs\\ApplicationInstallerStub.cs\" />\n    <Compile Include=\"Stubs\\ApplicationPoolStub.cs\" />\n    <Compile Include=\"Stubs\\ApplicationStub.cs\" />\n    <Compile Include=\"Stubs\\ProcessStub.cs\" />\n    <Compile Include=\"System\\SystemExtensionsTest.cs\" />\n    <Compile Include=\"Update\\ApplicationUpdateManagerTest.cs\" />\n    <Compile Include=\"Utils\\AssertUtils.cs\" />\n    <Compile Include=\"Utils\\TestUtils.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"Data\\ApplicationConfigParser\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\ApplicationPool\\test.myapp\\1.0.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\ApplicationPool\\test.myapp\\1.0.1\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\DeploymentConfig\\DeploymentConfig.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\DeploymentConfigFullIpcApp.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\DeploymentConfigNoApps.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\DeploymentConfigGracefulShutdownApp.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\DeploymentConfigMonitorInitApp.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\DeploymentConfigHeartBeatApp.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\DeploymentConfigWithProperties.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\DeploymentConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\DeploymentConfigUpdate.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\GracefulShutdownApp\\1.0.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\FullIpcApp\\1.0.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\MonitorInitApp\\1.0.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\HeartBeatApp\\1.0.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\test.app1\\1.0.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\test.app1\\1.0.1\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\test.app2\\1.1.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\test.app2\\2.0.0-beta\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\test.app3\\1.0.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\test.app3\\1.1.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Data\\EndToEndTest\\test.app4\\1.0.0\\AppConfig.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Etg.Yams.Test.xunit.runner.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n    <None Include=\"packages.config\">\n      <SubType>Designer</SubType>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"Data\\Exes\\HangingProcess.exe\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </Content>\n    <Content Include=\"Data\\Exes\\SuicidalProcess.exe\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </Content>\n    <Content Include=\"Data\\Exes\\TestProcess.exe\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </Content>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\AzureBlobStorageDeploymentRepository\\AzureBlobStorageDeploymentRepository.csproj\">\n      <Project>{DF95A9DC-F6BE-4C71-B444-4092B43EB602}</Project>\n      <Name>AzureBlobStorageDeploymentRepository</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\AzureUtils\\AzureUtils.csproj\">\n      <Project>{1C890E49-5A9B-4EAB-9F69-6A6E78D82610}</Project>\n      <Name>AzureUtils</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Common\\Common.csproj\">\n      <Project>{3e982150-5b43-44da-8d96-66cf07a9a14c}</Project>\n      <Name>Common</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Client\\Etg.Yams.Client.csproj\">\n      <Project>{d4624b9b-67a1-46d5-9468-58995b2720f9}</Project>\n      <Name>Etg.Yams.Client</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Core\\Etg.Yams.Core.csproj\">\n      <Project>{7145e485-34fa-4632-89b0-bd27c96af69c}</Project>\n      <Name>Etg.Yams.Core</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Ipc\\Etg.Yams.Ipc.csproj\">\n      <Project>{c7c03d37-f2d2-4115-8423-86c1bf1b8a18}</Project>\n      <Name>Etg.Yams.Ipc</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\AzureTestUtils\\AzureTestUtils.csproj\">\n      <Project>{84C08621-2C78-4B19-9454-7B9019E68326}</Project>\n      <Name>AzureTestUtils</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\HangingProcess\\HangingProcess.csproj\">\n      <Project>{1dd27caf-ac19-4674-a42b-f15260929baf}</Project>\n      <Name>HangingProcess</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\Stubs\\Stubs.csproj\">\n      <Project>{68cd41f8-a6c3-4d43-93ca-92e898254cbd}</Project>\n      <Name>Stubs</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\SuicidalProcess\\SuicidalProcess.csproj\">\n      <Project>{80a3b3bd-8d2f-471a-a198-576772faa048}</Project>\n      <Name>SuicidalProcess</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\TestProcess\\TestProcess.csproj\">\n      <Project>{aeaee225-1080-4cc9-8ba8-9f7580ed1b9b}</Project>\n      <Name>TestProcess</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <Service Include=\"{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\..\\packages\\xunit.runner.visualstudio.2.1.0\\build\\net20\\xunit.runner.visualstudio.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\packages\\xunit.runner.visualstudio.2.1.0\\build\\net20\\xunit.runner.visualstudio.props'))\" />\n  </Target>\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Etg.Yams.Test.xunit.runner.json",
    "content": "﻿{\n  \"methodDisplay\": \"method\",\n  \"parallelizeAssembly\": true,\n  \"parallelizeTestCollections\": true,\n  \"maxParallelThreads\": 8\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Install/ApplicationInstallerTest.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Install;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Test.stubs;\nusing Etg.Yams.Update;\nusing Semver;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Install\n{\n    public class ApplicationInstallerTest\n    {\n        private ApplicationInstaller _applicationInstaller;\n        private ApplicationPoolStub _applicationPool;\n        private readonly string _applicationsRoot;\n\n        public ApplicationInstallerTest()\n        {\n            _applicationsRoot = Path.Combine(Directory.GetCurrentDirectory(), \"ApplicationInstallerTest\");\n        }\n\n        [Fact]\n        public async Task TestInstallApplication()\n        {\n            _applicationPool = new ApplicationPoolStub();\n            IApplicationFactory applicationFactory = new ApplicationFactoryStub();\n            _applicationInstaller = new ApplicationInstaller(_applicationsRoot, applicationFactory, _applicationPool);\n\n            AppIdentity appIdentity = new AppIdentity(\"test.app\", new SemVersion(1,0,0));\n            await _applicationInstaller.Install(new AppInstallConfig(appIdentity));\n\n            Assert.True(_applicationPool.HasApplicationBeenAdded(appIdentity));\n        }\n\n        [Fact]\n        public async Task TestRemoveApplication()\n        {\n            _applicationPool = new ApplicationPoolStub();\n            IApplicationFactory applicationFactory = new ApplicationFactoryStub();\n            _applicationInstaller = new ApplicationInstaller(_applicationsRoot, applicationFactory, _applicationPool);\n\n            AppIdentity appIdentity = new AppIdentity(\"test.app\", new SemVersion(1, 0, 0));\n            _applicationInstaller.Install(new AppInstallConfig(appIdentity)).Wait();\n\n            // make sure the app directory exists because uninstall will try to delete it\n            string appPath = Path.Combine(_applicationsRoot, \"test.app\", \"1.0.0\");\n            if (!Directory.Exists(appPath))\n            {\n                Directory.CreateDirectory(appPath);\n            }\n            await _applicationInstaller.UnInstall(appIdentity);\n\n            Assert.False(_applicationPool.HasApplication(appIdentity));\n            Assert.False(Directory.Exists(appPath));\n        }\n\n        [Fact]\n        public async Task TestUpdateApplication()\n        {\n            IApplicationPool applicationPool = new ApplicationPoolStub();\n            IApplicationInstaller applicationInstaller = new ApplicationInstaller(_applicationsRoot, new ApplicationFactoryStub(), applicationPool);\n\n            const string appId = \"test.app\";\n            AppIdentity[] existingApps = { new AppIdentity(appId, new SemVersion(1, 0, 0)), new AppIdentity(appId, new SemVersion(1, 0, 1)) };\n            AppIdentity[] newApps = { new AppIdentity(appId, new SemVersion(1, 0, 2)), new AppIdentity(appId, new SemVersion(2, 0, 0)) };\n\n            foreach (var existingApp in existingApps)\n            {\n                string appPath = Path.Combine(_applicationsRoot, existingApp.Id, existingApp.Version.ToString());\n                if (!Directory.Exists(appPath))\n                {\n                    Directory.CreateDirectory(appPath);\n                }\n                await applicationInstaller.Install(new AppInstallConfig(existingApp));\n                Assert.True(applicationPool.HasApplication(existingApp));\n            }\n\n            await applicationInstaller.Update(existingApps, newApps.Select(appIdentity => new AppInstallConfig(appIdentity)));\n\n            foreach (AppIdentity app in existingApps)\n            {\n                Assert.False(applicationPool.HasApplication(app));\n            }\n\n            foreach (AppIdentity app in newApps)\n            {\n                Assert.True(applicationPool.HasApplication(app));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Process/GracefulShutdownProcessDecoratorTest.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Process;\nusing Xunit;\nusing Etg.Yams.Ipc;\nusing Etg.Yams.Application;\n\nnamespace Etg.Yams.Test.Process\n{\n    public class GracefulShutdownProcessDecoratorTest\n    {\n        [Fact]\n        public async Task TestThatExitedEventIsNotFiredOnGracefulShutdown()\n        {\n            var yamsConfig = new YamsConfigBuilder(\"clusterId\", \"1\", \"instanceId\", \"C:\\\\Foo\").Build();\n            var process = new StubIProcess().HasExited_Get(() => true);\n            IIpcConnection connection = new StubIIpcConnection()\n                .SendMessage(message =>\n                {\n                    process.Exited_Raise(process, new ProcessExitedArgs(\"\"));\n                    return Task.CompletedTask;\n                })\n                .Disconnect(() => Task.CompletedTask);\n            GracefulShutdownProcessDecorator decorator = new GracefulShutdownProcessDecorator(new AppIdentity(\"app\", \"1.0.0\"), yamsConfig, process, connection);\n            bool hasExitedFired = false;\n            decorator.Exited += (sender, args) =>\n            {\n                hasExitedFired = true;\n            };\n\n            await decorator.Close();\n            Assert.False(hasExitedFired);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Process/ProcessStopperTest.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Etg.Yams.Process;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Process\n{\n    public class ProcessStopperTest\n    {\n        [Fact]\n        public void TestThatProcessIsClosedFirst()\n        {\n            bool resourcesReleased = false;\n            bool hasExited = false;\n            IProcess process = new StubIProcess()\n                .Close(() =>\n                {\n                    hasExited = true;\n                    return Task.FromResult(true);\n                })\n                .Kill(() =>\n                {\n                    throw new Exception(\"Kill should not be called if the process has exited gracefully\");\n                })\n                .HasExited_Get(() => hasExited)\n                .ExePath_Get(() => \"exePath\")\n                .ReleaseResources(() =>\n                {\n                    resourcesReleased = true;\n                    return Task.FromResult(true);\n                }\n            );\n\n            IProcessStopper processStopper = new ProcessStopper(0);\n            processStopper.StopProcess(process);\n\n            Assert.True(hasExited);\n            Assert.True(resourcesReleased);\n        }\n\n        [Fact] \n        public void TestThatProcessIsKilledIfItWontClose()\n        {\n            bool resourcesReleased = false;\n            bool hasExited = false;\n            IProcess process = new StubIProcess()\n                .Close(() => Task.FromResult(true))\n                .Kill(() =>\n                {\n                    hasExited = true;\n                    return Task.FromResult(true);\n                })\n                .HasExited_Get(() => hasExited)\n                .ExePath_Get(() => \"exePath\")\n                .ReleaseResources(() =>\n                {\n                    resourcesReleased = true;\n                    return Task.FromResult(true);\n                }\n            );\n\n            IProcessStopper processStopper = new ProcessStopper(0);\n            processStopper.StopProcess(process);\n\n            Assert.True(hasExited);\n            Assert.True(resourcesReleased);\n        }\n\n        [Fact]\n        public void TestThatExceptionIsCaughtAndSwallowedIfKillBlowsUp()\n        {\n            IProcess process = new StubIProcess()\n                .Close(() => Task.FromResult(true))\n                .Kill(() =>\n                {\n                    throw new Exception(\"Process would not die!\");\n                })\n                .HasExited_Get(() => false)\n                .ExePath_Get(() => \"exePath\");\n\n            IProcessStopper processStopper = new ProcessStopper(0);\n            processStopper.StopProcess(process);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Process/ProcessTest.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Process;\nusing Etg.Yams.Test.Utils;\nusing Etg.Yams.Utils;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Process\n{\n    public class ProcessTestFixture\n    {\n        public readonly string SuicidalExePath;\n        public readonly string HangingExePath;\n\n        public readonly AppIdentity HangingProcessIdentity = new AppIdentity(\"SuicidalProcess\", \"2.0.0\");\n        public readonly AppIdentity SuicidalProcessIdentity = new AppIdentity(\"HangingProcess\", \"1.1.4-alpha3\");\n        const string SuicidalProcessExeName = \"SuicidalProcess.exe\";\n        const string HangingProcessExeName = \"HangingProcess.exe\";\n\n        public ProcessTestFixture()\n        {\n            var testDirPath = Path.Combine(Directory.GetCurrentDirectory(), \"ProcessTest\");\n            SuicidalExePath = Path.Combine(testDirPath, SuicidalProcessExeName);\n            HangingExePath = Path.Combine(testDirPath, HangingProcessExeName);\n\n            Directory.CreateDirectory(testDirPath);\n            TestUtils.CopyExesTestDir(testDirPath);\n        }\n    }\n\n    public class ProcessTest : IClassFixture<ProcessTestFixture>\n    {\n        readonly ProcessTestFixture _fixture;\n        public ProcessTest(ProcessTestFixture fixture)\n        {\n            _fixture = fixture;\n        }\n\n        [Fact]\n        public async Task TestIsRunning()\n        {\n            IProcess hangingProcess = new Yams.Process.Process(_fixture.HangingProcessIdentity, _fixture.HangingExePath, false, new Os.System());\n            Assert.False(hangingProcess.IsRunning);\n            await hangingProcess.Start(string.Empty);\n            Assert.True(hangingProcess.IsRunning);\n            await hangingProcess.Kill();\n            Assert.True(await ProcessUtils.SpinWaitForExit(hangingProcess, 5));\n            Assert.False(hangingProcess.IsRunning);\n        }\n\n        [Fact]\n        public async Task TestThatProcessCannotBeStartedMoreThanOnce()\n        {\n            IProcess hangingProcess = new Yams.Process.Process(_fixture.HangingProcessIdentity, _fixture.HangingExePath, false, new Os.System());\n            await hangingProcess.Start(string.Empty);\n            Assert.True(hangingProcess.IsRunning);\n\n            await Assert.ThrowsAnyAsync<Exception>(async () => await hangingProcess.Start(string.Empty));\n            await hangingProcess.Kill();\n            await hangingProcess.ReleaseResources();\n        }\n\n        [Fact]\n        public async Task TestReleaseResources()\n        {\n            IProcess hangingProcess = new Yams.Process.Process(_fixture.HangingProcessIdentity, _fixture.HangingExePath, false, new Os.System());\n            await hangingProcess.ReleaseResources(); // should do nothing\n            await hangingProcess.Start(string.Empty);\n            Assert.True(hangingProcess.IsRunning);\n\n            await Assert.ThrowsAnyAsync<Exception>(async () => await hangingProcess.ReleaseResources());\n\n            await hangingProcess.Kill();\n            await hangingProcess.ReleaseResources();\n        }\n\n        [Fact(Skip = \"For some reason this test is flaky on CI builds. Disabling for now..\")]\n        public async Task TestThatExitedEventIsFired()\n        {\n            IProcess suicidalProcess = new Yams.Process.Process(_fixture.SuicidalProcessIdentity, _fixture.SuicidalExePath, false, new Os.System());\n            bool exitedFired = false;\n            suicidalProcess.Exited += (sender, args) =>\n            {\n                exitedFired = true;\n            };\n            await suicidalProcess.Start(string.Empty);\n            Assert.True(await ProcessUtils.SpinWaitForExit(suicidalProcess, 5));\n            Assert.True(exitedFired);\n            await suicidalProcess.ReleaseResources();\n        }\n\n        [Fact]\n        public async Task TestProperties()\n        {\n            const string exeArgs = \"arggg\";\n            IProcess suicidalProcess = new Yams.Process.Process(_fixture.SuicidalProcessIdentity, _fixture.SuicidalExePath, false, new Os.System());\n            await suicidalProcess.Start(exeArgs);\n            Assert.Equal(_fixture.SuicidalExePath, suicidalProcess.ExePath);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Process/SelfRestartingProcessTest.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Etg.Yams.Process;\nusing Etg.Yams.Test.stubs;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Process\n{\n    public class SelfRestartingProcessTest\n    {\n        [Fact]\n        public async Task TestThatProcessIsRestarted()\n        {\n            ProcessStub process = new ProcessStub(\"exePath\");\n\n            SelfRestartingProcess selfRestartingProcess = new SelfRestartingProcess(process, 1);\n            await selfRestartingProcess.Start(\"exeArgs\");\n            Assert.True(process.IsRunning);\n\n            process.RaiseExitedEvent();\n            Assert.True(await SpinWaitForRestart(selfRestartingProcess, 1));\n            Assert.True(process.IsRunning);\n        }\n\n        [Fact]\n        public async Task TestThatExitedIsRaisedIfProcessFailsToRestart()\n        {\n            ProcessStub process = new ProcessStub(\"exePath\");\n            SelfRestartingProcess selfRestartingProcess = new SelfRestartingProcess(process, 1);\n            bool exitedFired = false;\n            selfRestartingProcess.Exited += (sender, args) => {\n                exitedFired = true;\n            };\n\n            await selfRestartingProcess.Start(\"exeArgs\");\n            Assert.True(process.IsRunning);\n\n            process.ShouldStart = false;\n            process.RaiseExitedEvent();\n\n            Assert.True(await SpinWaitFor(() => exitedFired));\n            Assert.False(process.IsRunning);\n            Assert.True(exitedFired);\n        }\n\n        [Fact]\n        public async Task TestThatExitedIsRaisedIfProcessMaxRetryCountIsReached()\n        {\n            ProcessStub process = new ProcessStub(\"exePath\");\n            SelfRestartingProcess selfRestartingProcess = new SelfRestartingProcess(process, 1);\n            bool exitedFired = false;\n            selfRestartingProcess.Exited += (sender, args) =>\n            {\n                exitedFired = true;\n            };\n\n            await selfRestartingProcess.Start(\"exeArgs\");\n            Assert.True(process.IsRunning);\n\n            process.RaiseExitedEvent();\n            Assert.True(await SpinWaitForRestart(selfRestartingProcess, 1));\n            Assert.True(process.IsRunning);\n\n            process.RaiseExitedEvent();\n            Assert.True(await SpinWaitFor(() => exitedFired));\n            Assert.False(process.IsRunning);\n            Assert.True(exitedFired);\n            \n        }\n\n        private Task<bool> SpinWaitForRestart(SelfRestartingProcess selfRestartingProcess, int restartCount)\n        {\n            return SpinWaitFor(() => selfRestartingProcess.RestartCount == restartCount);\n        }\n\n        private async Task<bool> SpinWaitFor(Func<bool> func)\n        {\n            int totalWaitTime = 1000;\n            const int waitIncrement = 100;\n            while (!func() && totalWaitTime > 0)\n            {\n                await Task.Delay(waitIncrement);\n                totalWaitTime -= waitIncrement;\n            }\n            return func();\n        }\n\n        \n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Etg.Yams.Test\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Etg.Yams.Test\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"98b0ae89-5d42-4366-9c0e-9392737e36ac\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Storage/DeploymentConfigTest.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Linq;\nusing Etg.Yams.Application;\nusing Etg.Yams.Json;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Test.Utils;\nusing Xunit;\nusing Newtonsoft.Json.Linq;\nusing Newtonsoft.Json.Serialization;\n\nnamespace Etg.Yams.Test.Storage\n{\n    public class DeploymentConfigTestFixture\n    {\n        public DeploymentConfig DeploymentConfig { get; private set; }\n        public string DeploymentConfigJson { get; private set; }\n        public IDeploymentConfigSerializer DeploymentConfigSerializer { get; }\n\n        private readonly string _deploymentConfigFilePath = Path.Combine(\"Data\", \"DeploymentConfig\",\n            \"DeploymentConfig.json\");\n\n        public DeploymentConfigTestFixture()\n        {\n            DeploymentConfigSerializer = new JsonDeploymentConfigSerializer(new JsonSerializer(new DiagnosticsTraceWriter()));\n            DeploymentConfig = ParseTestDeploymentConfig();\n        }\n\n        public DeploymentConfig ParseTestDeploymentConfig()\n        {\n            DeploymentConfigJson = File.ReadAllText(_deploymentConfigFilePath);\n            return DeploymentConfigSerializer.Deserialize(DeploymentConfigJson);\n        }\n    }\n    public class DeploymentConfigTest : IClassFixture<DeploymentConfigTestFixture>\n    {\n        private readonly DeploymentConfigTestFixture _fixture;\n        private DeploymentConfig _deploymentConfig;\n        private readonly IDeploymentConfigSerializer _serializer;\n        public DeploymentConfigTest(DeploymentConfigTestFixture fixture)\n        {\n            _fixture = fixture;\n            _deploymentConfig = fixture.DeploymentConfig;\n            _serializer = fixture.DeploymentConfigSerializer;\n        }\n\n        [Fact]\n        public void TestListApplications()\n        {\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"app1\", \"app2\", \"app3\" },\n                _deploymentConfig.ListApplications());\n        }\n\n        [Fact]\n        public void TestListApplicationsForGivenClusterId()\n        {\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"app1\", \"app2\" },\n                _deploymentConfig.ListApplications(\"clusterId1\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"app1\" },\n                _deploymentConfig.ListApplications(\"clusterId2\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"app3\" },\n                _deploymentConfig.ListApplications(\"clusterId3\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new string[] { },\n                _deploymentConfig.ListApplications(\"clusterId4\"));\n        }\n\n        [Fact]\n        public void TestListVersions()\n        {\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"1.0.0\", \"1.0.1\" }, _deploymentConfig.ListVersions(\"app1\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"2.0.0-beta\" }, _deploymentConfig.ListVersions(\"app3\"));\n        }\n\n        [Fact]\n        public void TestListVersionsForAnAppThatIsNotThere()\n        {\n            Assert.False(_deploymentConfig.ListVersions(\"UnknownApp\").Any());\n        }\n\n        [Fact]\n        public void TestListVersionsWithClusterId()\n        {\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"1.0.0\", \"1.0.1\" },\n                _deploymentConfig.ListVersions(\"app1\", \"clusterId1\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"1.0.1\" },\n                _deploymentConfig.ListVersions(\"app1\", \"clusterId2\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new string[] { },\n                _deploymentConfig.ListVersions(\"app1\", \"clusterId13\"));\n        }\n\n        [Fact]\n        public void TestListVersionsWithClusterIdForAnAppThatIsNotThere()\n        {\n            Assert.False(_deploymentConfig.ListVersions(\"UnknownApp\", \"clusterId1\").Any());\n        }\n\n        [Fact]\n        public void TestListDeploymentsForApp()\n        {\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"clusterId1\", \"clusterId2\" },\n                _deploymentConfig.ListClusters(\"app1\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"clusterId3\" },\n                _deploymentConfig.ListClusters(\"app3\"));\n        }\n\n        [Fact]\n        public void TestListDeploymentsForAppThatIsNotThere()\n        {\n            Assert.False(_deploymentConfig.ListClusters(\"UnknownApp\").Any());\n        }\n\n        [Fact]\n        public void TestListDeploymentsForVersion()\n        {\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"clusterId1\" },\n                _deploymentConfig.ListClusters(new AppIdentity(\"app1\", \"1.0.0\")));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"clusterId1\", \"clusterId2\" },\n                _deploymentConfig.ListClusters(new AppIdentity(\"app1\", \"1.0.1\")));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"clusterId3\" },\n                _deploymentConfig.ListClusters(new AppIdentity(\"app3\", \"2.0.0-beta\")));\n        }\n\n        [Fact]\n        public void TestListDeploymentsForVersionThatIsNotThere()\n        {\n            Assert.False(_deploymentConfig.ListClusters(new AppIdentity(\"app1\", \"5.0.0\")).Any());\n        }\n\n        [Fact]\n        public void TestListDeploymentsForVersionButAppIsNotThere()\n        {\n            Assert.False(_deploymentConfig.ListClusters(new AppIdentity(\"app13\", \"1.0.0\")).Any());\n        }\n\n        [Fact]\n        public void TestAddDeploymentForNewApp()\n        {\n            _deploymentConfig = _deploymentConfig.AddApplication(new AppIdentity(\"app13\", \"1.0.13\"), \"clusterId13\");\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"app1\", \"app2\", \"app3\", \"app13\" },\n                _deploymentConfig.ListApplications());\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"1.0.13\" }, _deploymentConfig.ListVersions(\"app13\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"clusterId13\" },\n                _deploymentConfig.ListClusters(\"app13\"));\n        }\n\n        [Fact]\n        public void TestAddDeploymentForExistingApp()\n        {\n            _deploymentConfig = _deploymentConfig.AddApplication(new AppIdentity(\"app3\", \"1.0.13\"), \"clusterId13\");\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"1.0.13\", \"2.0.0-beta\" }, _deploymentConfig.ListVersions(\"app3\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"clusterId3\", \"clusterId13\" },\n                _deploymentConfig.ListClusters(\"app3\"));\n        }\n\n        [Fact]\n        public void TestAddDeploymentForExistingVersion()\n        {\n            _deploymentConfig = _deploymentConfig.AddApplication(new AppIdentity(\"app2\", \"1.0.0\"), \"clusterId13\");\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"1.0.0\" }, _deploymentConfig.ListVersions(\"app2\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"clusterId1\", \"clusterId13\" },\n                _deploymentConfig.ListClusters(\"app2\"));\n        }\n\n        [Fact]\n        public void TestAddExistingDeployment()\n        {\n            _deploymentConfig.AddApplication(new AppIdentity(\"app2\", \"1.0.0\"), \"clusterId1\");\n        }\n\n        [Fact]\n        public void TestRemoveApplication()\n        {\n            _deploymentConfig = _deploymentConfig.RemoveApplication(\"app1\");\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"app2\", \"app3\" }, _deploymentConfig.ListApplications());\n        }\n\n        [Fact]\n        public void TestThatRemoveApplicationForAnAppThatIsNotThere()\n        {\n            Assert.Throws<InvalidOperationException>(() =>\n            _deploymentConfig.RemoveApplication(\"UnknownApp\"));\n        }\n\n        [Fact]\n        public void TestRemoveVersion()\n        {\n            _deploymentConfig = _deploymentConfig.RemoveApplication(new AppIdentity(\"app1\", \"1.0.0\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"1.0.1\" }, _deploymentConfig.ListVersions(\"app1\"));\n        }\n\n        [Fact]\n        public void TestThatRemoveLastVersionAlsoRemovesTheApp()\n        {\n            _deploymentConfig = _deploymentConfig.RemoveApplication(new AppIdentity(\"app2\", \"1.0.0\"));\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"app1\", \"app3\" }, _deploymentConfig.ListApplications());\n        }\n\n        [Fact]\n        public void TestRemoveVersionForAnAppThatIsNotThere()\n        {\n            Assert.Throws<InvalidOperationException>(() =>\n           _deploymentConfig.RemoveApplication(new AppIdentity(\"app13\", \"1.0.0\")));\n        }\n\n        [Fact]\n        public void TestRemoveVersionThatIsNotThere()\n        {\n            Assert.Throws<InvalidOperationException>(() =>\n           _deploymentConfig.RemoveApplication(new AppIdentity(\"app1\", \"1.0.13\")));\n        }\n\n        [Fact]\n        public void TestRemoveDeployment()\n        {\n            _deploymentConfig = _deploymentConfig.RemoveApplication(new AppIdentity(\"app1\", \"1.0.1\"), \"clusterId2\");\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"clusterId1\" },\n                _deploymentConfig.ListClusters(\"app1\"));\n        }\n\n        [Fact]\n        public void TestThatRemoveLastDeploymentAlsoRemovesVersion()\n        {\n            _deploymentConfig = _deploymentConfig.RemoveApplication(new AppIdentity(\"app1\", \"1.0.0\"), \"clusterId1\");\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"1.0.1\" }, _deploymentConfig.ListVersions(\"app1\"));\n        }\n\n        [Fact]\n        public void TestThatRemoveLastDeploymentAlsoRemovesApplication()\n        {\n            _deploymentConfig = _deploymentConfig.RemoveApplication(new AppIdentity(\"app3\", \"2.0.0-beta\"), \"clusterId3\");\n            AssertUtils.ContainsSameElementsInAnyOrder(new[] { \"app1\", \"app2\" }, _deploymentConfig.ListApplications());\n        }\n\n        [Fact]\n        public void TestRemoveDeploymentForAnAppThatIsNotThere()\n        {\n            Assert.Throws<InvalidOperationException>(() =>\n           _deploymentConfig.RemoveApplication(new AppIdentity(\"app13\", \"1.0.0\"), \"clusterId13\"));\n        }\n\n        [Fact]\n        public void TestRemoveDeploymentForAVersionThatIsNotThere()\n        {\n            Assert.Throws<InvalidOperationException>(() =>\n           _deploymentConfig.RemoveApplication(new AppIdentity(\"app1\", \"13.0.0\"), \"clusterId13\"));\n        }\n\n        [Fact]\n        public void TestRemoveADeploymentThatIsNotThere()\n        {\n           _deploymentConfig.RemoveApplication(new AppIdentity(\"app1\", \"1.0.0\"), \"clusterId13\");\n        }\n\n        [Fact]\n        public void TestSerializeRoundTrip()\n        {\n            string serialized = JObject.Parse(_serializer.Serialize(_deploymentConfig)).ToString();\n            DeploymentConfig deploymentConfig = _serializer.Deserialize(serialized);\n            string roundTripJson = JObject.Parse(_serializer.Serialize(deploymentConfig)).ToString();\n            Assert.Equal(_deploymentConfig, deploymentConfig);\n            Assert.Equal(serialized, roundTripJson);\n        }\n\n        [Fact]\n        public void TestHasApplication_appId()\n        {\n            Assert.True(_deploymentConfig.HasApplication(\"app1\"));\n            Assert.False(_deploymentConfig.HasApplication(\"app13\"));\n        }\n\n        [Fact]\n        public void TestHasApplication_appId_version()\n        {\n            Assert.True(_deploymentConfig.HasApplication(new AppIdentity(\"app1\", \"1.0.0\")));\n            Assert.False(_deploymentConfig.HasApplication(new AppIdentity(\"app1\", \"1.0.13\")));\n            Assert.False(_deploymentConfig.HasApplication(new AppIdentity(\"app13\", \"1.0.0\")));\n        }\n\n        [Fact]\n        public void TestHasApplication_appId_version_clusterId()\n        {\n            Assert.True(_deploymentConfig.HasApplication(new AppIdentity(\"app1\", \"1.0.0\"), \"clusterId1\"));\n            Assert.True(_deploymentConfig.HasApplication(new AppIdentity(\"app1\", \"1.0.1\"), \"clusterId2\"));\n            Assert.False(_deploymentConfig.HasApplication(new AppIdentity(\"app1\", \"1.0.0\"), \"clusterId13\"));\n            Assert.False(_deploymentConfig.HasApplication(new AppIdentity(\"app1\", \"1.0.13\"), \"clusterId1\"));\n        }\n\n        [Fact]\n        public void TestThatPropertiesAreParsed()\n        {\n            AppDeploymentConfig config = _deploymentConfig.GetApplicationConfig(new AppIdentity(\"app2\", \"1.0.0\"));\n            Assert.True(config.Properties.ContainsKey(\"NodeType\"));\n            Assert.Equal(\"PROD\", config.Properties[\"NodeType\"]);\n        }\n\n        [Fact]\n        public void TestSetApplicationConfig()\n        {\n            AppIdentity appIdentity = new AppIdentity(\"newApp\", \"1.0.0\");\n            AppDeploymentConfig config = new AppDeploymentConfig(appIdentity, new [] {\"clusterId1\"});\n            config = config.AddProperty(\"Foo\", \"Bar\");\n            var deploymentConfig = _deploymentConfig.SetApplicationConfig(config);\n            Assert.Equal(\"Bar\", deploymentConfig.GetApplicationConfig(appIdentity).Properties[\"Foo\"]);\n        }\n\n        [Fact]\n        public void TestThatSetApplicationConfigOverwritesExisting()\n        {\n            AppIdentity appIdentity = new AppIdentity(\"app1\", \"1.0.0\");\n            AppDeploymentConfig config = _deploymentConfig.GetApplicationConfig(appIdentity);\n            config = config.AddProperty(\"key1\", \"value1\");\n            var deploymentConfig = _deploymentConfig.SetApplicationConfig(config);\n            Assert.Equal(\"value1\", deploymentConfig.GetApplicationConfig(appIdentity).Properties[\"key1\"]);\n\n            config = config.AddProperty(\"key2\", \"value2\");\n            deploymentConfig = deploymentConfig.SetApplicationConfig(config);\n            Assert.Equal(\"value1\", deploymentConfig.GetApplicationConfig(appIdentity).Properties[\"key1\"]);\n            Assert.Equal(\"value2\", deploymentConfig.GetApplicationConfig(appIdentity).Properties[\"key2\"]);\n        }\n\n        [Fact]\n        public void TestEqualsAndHashCode()\n        {\n            DeploymentConfig deploymentConfig = _fixture.ParseTestDeploymentConfig();\n            Assert.Equal(_deploymentConfig, deploymentConfig);\n            Assert.Equal(_deploymentConfig.GetHashCode(), deploymentConfig.GetHashCode());\n        }\n    }\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Storage/LocalDeploymentRepository.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Storage.Status;\nusing Etg.Yams.Utils;\n\nnamespace Etg.Yams.Test.Storage\n{\n    public class LocalDeploymentRepository : IDeploymentRepository, IDeploymentStatusReader, IDeploymentStatusWriter\n    {\n        private readonly string _path;\n        private readonly string _deploymentConfigPath;\n        private readonly IDeploymentConfigSerializer _deploymentConfigSerializer;\n        private readonly IDeploymentStatusSerializer _deploymentStatusSerializer;\n\n        public LocalDeploymentRepository(string path, IDeploymentConfigSerializer deploymentConfigSerializer, \n            IDeploymentStatusSerializer deploymentStatusSerializer)\n        {\n            _path = path;\n            _deploymentConfigPath = Path.Combine(_path, Constants.DeploymentConfigFileName);\n            _deploymentConfigSerializer = deploymentConfigSerializer;\n            _deploymentStatusSerializer = deploymentStatusSerializer;\n        }\n\n        public Task<DeploymentConfig> FetchDeploymentConfig()\n        {\n            string data = File.ReadAllText(_deploymentConfigPath);\n            return Task.FromResult(_deploymentConfigSerializer.Deserialize(data));\n        }\n\n        public Task PublishDeploymentConfig(DeploymentConfig deploymentConfig)\n        {\n            File.WriteAllText(_deploymentConfigPath, _deploymentConfigSerializer.Serialize(deploymentConfig));\n            return Task.CompletedTask;\n        }\n\n        public Task UploadApplicationBinaries(AppIdentity appIdentity, string localPath, ConflictResolutionMode conflictResolutionMode)\n        {\n            if (FileUtils.DirectoryDoesntExistOrEmpty(localPath))\n            {\n                throw new BinariesNotFoundException(\n                    $\"Binaries were not be uploaded because they were not found at the given path {localPath}\");\n            }\n\n            string destPath = GetBinariesPath(appIdentity);\n            bool binariesExist = FileUtils.DirectoryDoesntExistOrEmpty(destPath);\n            if (binariesExist)\n            {\n                if (conflictResolutionMode == ConflictResolutionMode.DoNothingIfBinariesExist)\n                {\n                    return Task.CompletedTask;\n                }\n                if (conflictResolutionMode == ConflictResolutionMode.FailIfBinariesExist)\n                {\n                    throw new DuplicateBinariesException();\n                }\n            }\n            return FileUtils.CopyDir(_path, localPath, true);\n        }\n\n        private string GetBinariesPath(AppIdentity appIdentity)\n        {\n            return Path.Combine(_path, GetDeploymentRelativePath(appIdentity));\n        }\n\n        private static string GetDeploymentRelativePath(AppIdentity appIdentity)\n        {\n            return Path.Combine(appIdentity.Id, appIdentity.Version.ToString());\n        }\n\n        public Task DeleteApplicationBinaries(AppIdentity appIdentity)\n        {\n            string path = GetBinariesPath(appIdentity);\n            if (FileUtils.DirectoryDoesntExistOrEmpty(path))\n            {\n                throw new BinariesNotFoundException(\n                    $\"Cannot delete binaries for application {appIdentity} because they were not found\");\n            }\n            Directory.Delete(path, true);\n            return Task.CompletedTask;\n        }\n\n        public Task<bool> HasApplicationBinaries(AppIdentity appIdentity)\n        {\n            string path = GetBinariesPath(appIdentity);\n            return Task.FromResult(!FileUtils.DirectoryDoesntExistOrEmpty(path));\n        }\n\n        public async Task DownloadApplicationBinaries(AppIdentity appIdentity, string localPath, ConflictResolutionMode conflictResolutionMode)\n        {\n            bool exists = !FileUtils.DirectoryDoesntExistOrEmpty(localPath);\n            if (exists)\n            {\n                if (conflictResolutionMode == ConflictResolutionMode.DoNothingIfBinariesExist)\n                {\n                    return;\n                }\n                if (conflictResolutionMode == ConflictResolutionMode.FailIfBinariesExist)\n                {\n                    throw new DuplicateBinariesException(\n                        $\"Cannot download the binaries because the destination directory {localPath} contains files\");\n                }\n            }\n\n            string path = GetBinariesPath(appIdentity);\n            if (FileUtils.DirectoryDoesntExistOrEmpty(path))\n            {\n                throw new BinariesNotFoundException($\"The binaries were not found in the Yams repository\");\n            }\n            await FileUtils.CopyDir(path, localPath, true);\n        }\n\n        public Task<InstanceDeploymentStatus> FetchInstanceDeploymentStatus(string clusterId, string instanceId)\n        {\n            string path = GetInstanceDeploymentStatusPath(clusterId, instanceId);\n            string data = File.ReadAllText(path);\n            return Task.FromResult(_deploymentStatusSerializer.Deserialize(data));\n        }\n\n        public Task PublishInstanceDeploymentStatus(string clusterId, string instanceId,\n            InstanceDeploymentStatus instanceDeploymentStatus)\n        {\n            string path = GetInstanceDeploymentStatusPath(clusterId, instanceId);\n            string parentDirPath = Path.GetDirectoryName(path);\n            if (!Directory.Exists(parentDirPath))\n            {\n                Directory.CreateDirectory(parentDirPath);\n            }\n            File.WriteAllText(path, _deploymentStatusSerializer.Serialize(instanceDeploymentStatus));\n            return Task.CompletedTask;\n        }\n\n        private string GetInstanceDeploymentStatusPath(string clusterId, string instanceId)\n        {\n            return $\"{_path}/clusters/{clusterId}/instances/{instanceId}\";\n        }\n    }\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/System/SystemExtensionsTest.cs",
    "content": "﻿using Etg.Yams.Os;\nusing System;\nusing Xunit;\n\nnamespace Etg.Yams.Test.System\n{\n    public class SystemExtensionsTest\n    {\n        [Theory]\n        [InlineData(\"C:\\\\Windows;C:\\\\Foo;\", \"C:\\\\Windows;D:\\\\Bar\\\\\", \"C:\\\\Windows;C:\\\\Foo;D:\\\\Bar\\\\;\")]\n        [InlineData(\"C:\\\\Windows;C:\\\\Foo;\", null, \"C:\\\\Windows;C:\\\\Foo;\")]\n        [InlineData(null, \"C:\\\\Windows;C:\\\\Foo\\\\;\", \"C:\\\\Windows;C:\\\\Foo\\\\;\")]\n        [InlineData(\"C:\\\\Windows;C:\\\\Foo\", \"C:\\\\Windows;C:\\\\Foo\\\\;\", \"C:\\\\Windows;C:\\\\Foo;C:\\\\Foo\\\\;\")]\n        public void TestGetPath(string processPath, string machinePath, string expectedResult)\n        {\n            ISystem systemStub = new StubISystem()\n                .GetEnvironmentVariable((string name, EnvironmentVariableTarget target) =>\n                {\n                    if (name != \"PATH\")\n                    {\n                        return null;\n                    }\n                    return target == EnvironmentVariableTarget.Machine ? machinePath : processPath;\n                });\n            string actualResult = systemStub.GetPathEnvironmentVariable(); // calling extension method\n            Assert.Equal(actualResult, expectedResult);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Update/ApplicationUpdateManagerTest.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Deploy;\nusing Etg.Yams.Download;\nusing Etg.Yams.Storage.Config;\nusing Etg.Yams.Test.stubs;\nusing Etg.Yams.Update;\nusing Semver;\nusing Xunit;\nusing Etg.Yams.Storage;\nusing Etg.Yams.Storage.Status;\nusing Etg.Yams.Install;\nusing System;\n\nnamespace Etg.Yams.Test.Update\n{\n    public class ApplicationUpdateManagerTest\n    {\n        private readonly AppIdentity app1v1;\n        private readonly AppIdentity app1v2;\n        private readonly AppIdentity app1v3;\n        private readonly AppIdentity app1v4;\n        private readonly AppIdentity app1v5;\n        private readonly List<AppIdentity> downloadedApps;\n        private readonly StubIApplicationDownloader applicationDownloader;\n        private readonly ApplicationPoolStub applicationPool;\n        private readonly ApplicationInstallerStub applicationInstaller;\n\n        private InstanceDeploymentStatus instanceDeploymentStatus;\n        private readonly StubIDeploymentStatusWriter deploymentStatusWriterStub;\n\n        public ApplicationUpdateManagerTest()\n        {\n            string id1 = \"appId1\";\n            var v1 = SemVersion.Parse(\"1.0.0\");\n            var v2 = SemVersion.Parse(\"2.0.0\");\n            var v3 = SemVersion.Parse(\"3.0.0\");\n            var v4 = SemVersion.Parse(\"4.0.0\");\n            var v5 = SemVersion.Parse(\"5.0.0\");\n\n            app1v1 = new AppIdentity(id1, v1);\n            app1v2 = new AppIdentity(id1, v2);\n            app1v3 = new AppIdentity(id1, v3);\n            app1v4 = new AppIdentity(id1, v4);\n            app1v5 = new AppIdentity(id1, v5);\n\n            downloadedApps = new List<AppIdentity>();\n            applicationDownloader = new StubIApplicationDownloader()\n                .DownloadApplication(appIdentity =>\n                {\n                    downloadedApps.Add(appIdentity);\n                    return Task.FromResult(true);\n                }\n            );\n\n            applicationPool = new ApplicationPoolStub();\n            applicationInstaller = new ApplicationInstallerStub(applicationPool, \"path\");\n\n            instanceDeploymentStatus = new InstanceDeploymentStatus();\n            deploymentStatusWriterStub = new StubIDeploymentStatusWriter()\n                .PublishInstanceDeploymentStatus((clusterId, instanceId, status) =>\n                {\n                    instanceDeploymentStatus = status;\n                    return Task.CompletedTask;\n                });\n        }\n\n        [Fact]\n        public async Task TestMultipleUpdates()\n        {\n            IEnumerable<AppIdentity> appsToDeploy = new[] {app1v3, app1v4, app1v5};\n            IEnumerable<string> clusters = new[] {\"clusterId1\"};\n\n\t        IApplicationDeploymentDirectory applicationDeploymentDirectory = new StubIApplicationDeploymentDirectory()\n\t\t        .FetchDeployments(() => Task.FromResult(appsToDeploy.Select(identity => new AppDeploymentConfig(identity, clusters))));\n\n            string path = Path.GetTempPath();\n            await applicationPool.AddApplication(new ApplicationStub(app1v1, path));\n            await applicationPool.AddApplication(new ApplicationStub(app1v2, path));\n            await applicationPool.AddApplication(new ApplicationStub(app1v3, path));\n\n            IUpdateSessionManager updateSessionManagerStub = new StubIUpdateSessionManager()\n                .TryStartUpdateSession(() => Task.FromResult(true))\n                .EndUpdateSession(() => Task.CompletedTask);\n\n            const string ClusterId = \"clusterId\";\n            const string InstanceId = \"instanceId\";\n            ApplicationUpdateManager applicationUpdateManager = new ApplicationUpdateManager(ClusterId, InstanceId, \n                applicationDeploymentDirectory, applicationPool, applicationDownloader, applicationInstaller,\n                deploymentStatusWriterStub, updateSessionManagerStub);\n            await applicationUpdateManager.CheckForUpdates();\n\n            Assert.Equal(3, applicationPool.Applications.Count());\n            Assert.True(applicationPool.HasApplication(app1v3));\n            Assert.True(applicationPool.HasApplication(app1v4));\n            Assert.True(applicationPool.HasApplication(app1v5));\n\n            Assert.Equal(3, instanceDeploymentStatus.Applications.Count());\n            VerifyThatDeploymentStatusHasBeenUpdated(instanceDeploymentStatus, app1v3, ClusterId, InstanceId);\n            VerifyThatDeploymentStatusHasBeenUpdated(instanceDeploymentStatus, app1v4, ClusterId, InstanceId);\n            VerifyThatDeploymentStatusHasBeenUpdated(instanceDeploymentStatus, app1v5, ClusterId, InstanceId);\n        }\n\n        [Fact]\n        public async Task TestThatUpdateDoesNothingIfCannotStartUpdateSession()\n        {\n            IEnumerable<AppIdentity> appsToDeploy = new[] { app1v2 };\n            IEnumerable<string> clusters = new[] { \"clusterId1\" };\n\n            IApplicationPool applicationPool = new ApplicationPoolStub();\n            string path = Path.GetTempPath();\n            await applicationPool.AddApplication(new ApplicationStub(app1v1, path));\n\n            IUpdateSessionManager updateSessionManagerStub = new StubIUpdateSessionManager()\n                .TryStartUpdateSession(() => Task.FromResult(false));\n\n            IApplicationDeploymentDirectory applicationDeploymentDirectory = new StubIApplicationDeploymentDirectory()\n                .FetchDeployments(() => Task.FromResult(appsToDeploy.Select(identity => new AppDeploymentConfig(identity, clusters))));\n\n            const string ClusterId = \"clusterId\";\n            const string InstanceId = \"instanceId\";\n            ApplicationUpdateManager applicationUpdateManager = new ApplicationUpdateManager(ClusterId, InstanceId,\n                applicationDeploymentDirectory, applicationPool, applicationDownloader, applicationInstaller,\n                deploymentStatusWriterStub, updateSessionManagerStub);\n            await applicationUpdateManager.CheckForUpdates();\n\n            Assert.Equal(1, applicationPool.Applications.Count());\n            Assert.True(applicationPool.HasApplication(app1v1));\n        }\n\n\n        [Fact]\n        public async Task TestThatUpdateSessionIsEndedFollowingASuccessfulUpdate()\n        {\n            IEnumerable<AppIdentity> appsToDeploy = new[] { app1v2 };\n            IEnumerable<string> clusters = new[] { \"clusterId1\" };\n\n            IApplicationPool applicationPool = new ApplicationPoolStub();\n            string path = Path.GetTempPath();\n            await applicationPool.AddApplication(new ApplicationStub(app1v1, path));\n\n            bool updateSessionEnded = false;\n            IUpdateSessionManager updateSessionManagerStub = new StubIUpdateSessionManager()\n                .TryStartUpdateSession(() => Task.FromResult(true))\n                .EndUpdateSession(() =>\n                {\n                    updateSessionEnded = true;\n                    return Task.CompletedTask;\n                });\n\n            IApplicationDeploymentDirectory applicationDeploymentDirectory = new StubIApplicationDeploymentDirectory()\n                .FetchDeployments(() => Task.FromResult(appsToDeploy.Select(identity => new AppDeploymentConfig(identity, clusters))));\n\n            var applicationInstallerStub = new StubIApplicationInstaller()\n                .Install((config) => throw new Exception(\"Failed to install application\"));\n            const string ClusterId = \"clusterId\";\n            const string InstanceId = \"instanceId\";\n            ApplicationUpdateManager applicationUpdateManager = new ApplicationUpdateManager(ClusterId, InstanceId,\n                applicationDeploymentDirectory, applicationPool, applicationDownloader, applicationInstallerStub,\n                deploymentStatusWriterStub, updateSessionManagerStub);\n            await applicationUpdateManager.CheckForUpdates();\n\n            Assert.False(updateSessionEnded);\n        }\n\n\n        [Fact]\n        public async Task TestThatUpdateSessionIsNotEndedWhenUpdateFails()\n        {\n            IEnumerable<AppIdentity> appsToDeploy = new[] { app1v2 };\n            IEnumerable<string> clusters = new[] { \"clusterId1\" };\n\n            IApplicationPool applicationPool = new ApplicationPoolStub();\n            string path = Path.GetTempPath();\n            await applicationPool.AddApplication(new ApplicationStub(app1v1, path));\n\n            bool updateSessionEnded = false;\n            IUpdateSessionManager updateSessionManagerStub = new StubIUpdateSessionManager()\n                .TryStartUpdateSession(() => Task.FromResult(true))\n                .EndUpdateSession(() =>\n                {\n                    updateSessionEnded = true;\n                    return Task.CompletedTask;\n                });\n\n            IApplicationDeploymentDirectory applicationDeploymentDirectory = new StubIApplicationDeploymentDirectory()\n                .FetchDeployments(() => Task.FromResult(appsToDeploy.Select(identity => new AppDeploymentConfig(identity, clusters))));\n\n            const string ClusterId = \"clusterId\";\n            const string InstanceId = \"instanceId\";\n            ApplicationUpdateManager applicationUpdateManager = new ApplicationUpdateManager(ClusterId, InstanceId,\n                applicationDeploymentDirectory, applicationPool, applicationDownloader, applicationInstaller,\n                deploymentStatusWriterStub, updateSessionManagerStub);\n            await applicationUpdateManager.CheckForUpdates();\n\n            Assert.True(updateSessionEnded);\n        }\n\n        private void VerifyThatDeploymentStatusHasBeenUpdated(InstanceDeploymentStatus deploymentStatus, \n            AppIdentity appIdentity, string clusterId, string instanceId)\n        {\n            var appDeploymentStatus = deploymentStatus.GetAppDeploymentStatus(appIdentity);\n            Assert.NotNull(appDeploymentStatus);\n            Assert.Equal(appIdentity, appDeploymentStatus.AppIdentity);\n            Assert.Equal(clusterId, appDeploymentStatus.ClusterId);\n            Assert.Equal(instanceId, appDeploymentStatus.InstanceId);\n            Assert.NotNull(appDeploymentStatus.UtcTimeStamp);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Utils/AssertUtils.cs",
    "content": "﻿using System.Collections.Generic;\nusing Xunit;\n\nnamespace Etg.Yams.Test.Utils\n{\n    public static class AssertUtils\n    {\n        public static void ContainsSameElementsInAnyOrder<T>(IEnumerable<T> expected, IEnumerable<T> actual)\n        {\n            Assert.True(new HashSet<T>(expected).SetEquals(actual),\n                \"The two enumerables do not contain the same set of elements\");\n        }\n    }\n}"
  },
  {
    "path": "test/Etg.Yams.Core.Test/Utils/TestUtils.cs",
    "content": "﻿using System.IO;\nusing System.Threading;\nusing Etg.Yams.Application;\nusing Etg.Yams.Utils;\n\nnamespace Etg.Yams.Test.Utils\n{\n    public static class TestUtils\n    {\n        public static string GetTestApplicationOutput(string applicationRootPath, AppIdentity appIdentity,\n            string exeName)\n        {\n            string processOutputPath = Path.Combine(Path.Combine(applicationRootPath,\n                ApplicationUtils.GetApplicationRelativePath(appIdentity)), $\"{exeName}.exe.out\");\n\n            int maxRetry = 10;\n            while (maxRetry-- > 0)\n            {\n                Thread.Sleep(100);\n                if (File.Exists(processOutputPath))\n                {\n                    break;\n                }\n            }\n\n            using (StreamReader reader = new StreamReader(processOutputPath))\n            {\n                return reader.ReadToEnd();\n            }\n        }\n\n        public static string GetTestExesDirPath()\n        {\n            return Path.Combine(Directory.GetCurrentDirectory(), \"Data\", \"Exes\");\n        }\n\n        public static void CopyExe(string exeName, string destPath)\n        {\n            File.Copy(Path.Combine(GetTestExesDirPath(), exeName), Path.Combine(destPath, exeName), overwrite: true);\n        }\n\n        public static void CopyExesTestDir(string destPath)\n        {\n            FileUtils.CopyDir(GetTestExesDirPath(), destPath, overwrite: true);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.Data.Services.Client\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-5.7.0.0\" newVersion=\"5.7.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.Data.OData\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-5.7.0.0\" newVersion=\"5.7.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.Data.Edm\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-5.7.0.0\" newVersion=\"5.7.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>"
  },
  {
    "path": "test/Etg.Yams.Core.Test/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net461\" />\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.7.0\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.7.0\" targetFramework=\"net461\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.7.0\" targetFramework=\"net461\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net461\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net461\" />\n  <package id=\"System.Spatial\" version=\"5.7.0\" targetFramework=\"net461\" />\n  <package id=\"xunit\" version=\"2.1.0\" targetFramework=\"net451\" />\n  <package id=\"xunit.abstractions\" version=\"2.0.0\" targetFramework=\"net451\" />\n  <package id=\"xunit.assert\" version=\"2.1.0\" targetFramework=\"net451\" />\n  <package id=\"xunit.core\" version=\"2.1.0\" targetFramework=\"net451\" />\n  <package id=\"xunit.extensibility.core\" version=\"2.1.0\" targetFramework=\"net451\" />\n  <package id=\"xunit.extensibility.execution\" version=\"2.1.0\" targetFramework=\"net451\" />\n  <package id=\"xunit.runner.console\" version=\"2.1.0\" targetFramework=\"net451\" />\n  <package id=\"xunit.runner.visualstudio\" version=\"2.1.0\" targetFramework=\"net451\" />\n</packages>"
  },
  {
    "path": "test/Etg.Yams.Core.Test/stubs/ApplicationFactoryStub.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Install;\nusing Etg.Yams.Storage.Config;\n\nnamespace Etg.Yams.Test.stubs\n{\n    public class ApplicationFactoryStub : IApplicationFactory\n    {\n        public Task<IApplication> CreateApplication(AppInstallConfig appInstallConfig, string appPath)\n        {\n            return Task.FromResult((IApplication)new ApplicationStub(appInstallConfig.AppIdentity, appPath));\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/stubs/ApplicationInstallerStub.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\nusing Etg.Yams.Install;\n\nnamespace Etg.Yams.Test.stubs\n{\n    public class ApplicationInstallerStub : IApplicationInstaller\n    {\n        private readonly IApplicationPool _applicationPool;\n        private readonly string path;\n\n        public ApplicationInstallerStub(IApplicationPool applicationPool, string path)\n        {\n            _applicationPool = applicationPool;\n            this.path = path;\n        }\n\n        public Task Install(AppInstallConfig appInstallConfig)\n        {\n            _applicationPool.AddApplication(new ApplicationStub(appInstallConfig.AppIdentity, GetAppPath(appInstallConfig)));\n            return Task.CompletedTask;\n        }\n\n        private string GetAppPath(AppInstallConfig appInstallConfig)\n        {\n            return $\"{path}\\\\{appInstallConfig.AppIdentity.Id}\\\\{appInstallConfig.AppIdentity.Version}\";\n        }\n\n        public Task UnInstall(AppIdentity appIdentity)\n        {\n            _applicationPool.RemoveApplication(appIdentity);\n            return Task.CompletedTask;\n        }\n\n        public Task<bool> Update(IEnumerable<AppIdentity> applicationsToRemove, IEnumerable<AppInstallConfig> applicationsToDeploy)\n        {\n            foreach (var appIdentity in applicationsToRemove)\n            {\n                _applicationPool.RemoveApplication(appIdentity);\n            }\n            foreach (var appInstallConfig in applicationsToDeploy)\n            {\n                _applicationPool.AddApplication(new ApplicationStub(appInstallConfig.AppIdentity, \"path\"));\n            }\n            return Task.FromResult(true);\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/stubs/ApplicationPoolStub.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\n\nnamespace Etg.Yams.Test.stubs\n{\n    public class ApplicationPoolStub : IApplicationPool\n    {\n        private readonly Dictionary<AppIdentity, IApplication> _applications;\n        private readonly HashSet<AppIdentity> _addedApplications;\n\n        public ApplicationPoolStub()\n        {\n            _applications = new Dictionary<AppIdentity, IApplication>();    \n            _addedApplications = new HashSet<AppIdentity>();\n        }\n\n        public Task AddApplication(IApplication application)\n        {\n            if (HasApplication(application.Identity))\n            {\n                throw new Exception(\"Attempt to add an existing application\");\n            }\n            _applications[application.Identity] = application;\n            _addedApplications.Add(application.Identity);\n            return Task.FromResult(true);\n        }\n\n        public Task RemoveApplication(AppIdentity appIdentity)\n        {\n            _applications.Remove(appIdentity);\n            return Task.FromResult(true);\n        }\n\n        public bool HasApplication(AppIdentity appIdentity)\n        {\n            return _applications.ContainsKey(appIdentity);\n        }\n\n        public IApplication GetApplication(AppIdentity appIdentity)\n        {\n            return _applications[appIdentity];\n        }\n\n        public IEnumerable<IApplication> Applications\n        {\n            get { return _applications.Values; }\n        }\n\n        public Task Shutdown()\n        {\n            return Task.FromResult(true);\n        }\n\n        public bool HasApplicationBeenAdded(AppIdentity appIdentity)\n        {\n            return _addedApplications.Contains(appIdentity);\n        }\n\n        public void Dispose()\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/stubs/ApplicationStub.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Etg.Yams.Application;\n\nnamespace Etg.Yams.Test.stubs\n{\n    public class ApplicationStub : IApplication\n    {\n        private bool _running;\n\n        public AppIdentity Identity { get; private set; }\n        public string Path { get; private set; }\n\n        public ApplicationStub(AppIdentity appIdentity, string path)\n        {\n            Identity = appIdentity;\n            Path = path;\n        }\n\n        public Task<bool> Start()\n        {\n            _running = true;\n            return Task.FromResult(true);\n        }\n\n        public Task Stop()\n        {\n            _running = false;\n            return Task.FromResult(true);\n        }\n\n        public bool IsRunning()\n        {\n            return _running;\n        }\n\n        public void Fail()\n        {\n            if (Exited != null) Exited(this, new ApplicationExitedArgs{AppIdentity = Identity});\n        }\n\n        public event EventHandler<ApplicationExitedArgs> Exited;\n        public void Dispose()\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/Etg.Yams.Core.Test/stubs/ProcessStub.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Etg.Yams.Process;\n\nnamespace Etg.Yams.Test.stubs\n{\n    public class ProcessStub : IProcess\n    {\n        private readonly string _exePath;\n        private string _exeArgs;\n\n        public ProcessStub(string exePath)\n        {\n            _exePath = exePath;\n            ShouldStart = true;\n        }\n\n        public string ExePath\n        {\n            get { return _exePath; }\n        }\n\n        public string ExeArgs\n        {\n            get { return _exeArgs; }\n        }\n\n        public Task Start(string exeArgs)\n        {\n            _exeArgs = exeArgs;\n            if (!ShouldStart)\n            {\n                throw new Exception(\"Cannot start process\");\n            }\n            IsRunning = true;\n            return Task.FromResult(true);\n        }\n\n        public Task Close()\n        {\n            IsRunning = false;\n            return Task.FromResult(true);\n        }\n\n        public Task Kill()\n        {\n            IsRunning = false;\n            return Task.FromResult(true);\n        }\n\n        public Task ReleaseResources()\n        {\n            IsRunning = false;\n            return Task.FromResult(true);\n        }\n\n        public bool HasExited\n        {\n            get { return !IsRunning; }\n        }\n\n        public bool IsRunning\n        {\n            get;\n            private set;\n        }\n\n        public bool ShouldStart { get; set; }\n\n        public void RaiseExitedEvent()\n        {\n            var failedEvent = Exited;\n            if (failedEvent == null) return;\n            failedEvent(this, new ProcessExitedArgs(\"process Exited event raised from stub\"));\n        }\n\n        public event EventHandler<ProcessExitedArgs> Exited;\n        public void Dispose()\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/FullIpcProcess/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.2\" />\n    </startup>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.WindowsAzure.Storage\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-8.4.0.0\" newVersion=\"8.4.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>"
  },
  {
    "path": "test/FullIpcProcess/FullIpcProcess.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{99F3A36C-7930-4670-A8B3-7137D891671D}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>FullIpcProcess</RootNamespace>\n    <AssemblyName>FullIpcProcess</AssemblyName>\n    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\bin\\Debug\\Data\\FullIpcProcess\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\bin\\Release\\Data\\FullIpcProcess\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\CommandLineParser.1.9.71\\lib\\net45\\CommandLine.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.ComponentModel.Composition\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Core.2.2.5\\lib\\net45\\System.Reactive.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Interfaces.2.2.5\\lib\\net45\\System.Reactive.Interfaces.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Linq.2.2.5\\lib\\net45\\System.Reactive.Linq.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-PlatformServices.2.2.5\\lib\\net45\\System.Reactive.PlatformServices.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Client\\Etg.Yams.Client.csproj\">\n      <Project>{d4624b9b-67a1-46d5-9468-58995b2720f9}</Project>\n      <Name>Etg.Yams.Client</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/FullIpcProcess/Program.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Threading.Tasks;\nusing Etg.Yams.Client;\n\nnamespace FullIpcProcess\n{\n    internal class Program\n    {\n        public static void Main(string[] args)\n        {\n            Run(args).Wait();\n        }\n\n        private static async Task Run(string[] args)\n        {\n            Console.WriteLine(\"args \" + string.Join(\" \", args));\n            var yamsClientConfig = new YamsClientConfigBuilder(args).Build();\n            var yamsClientFactory = new YamsClientFactory();\n\n            IYamsClient yamsClient = yamsClientFactory.CreateYamsClient(yamsClientConfig);\n\n            await Task.WhenAll(yamsClient.Connect(), Initialize());\n\n            bool exitMessageReceived = false;\n            yamsClient.ExitMessageReceived += (sender, eventArgs) =>\n            {\n                Console.WriteLine(\"Exit message received!\");\n                exitMessageReceived = true;\n            };\n\n            File.WriteAllText($\"FullIpcApp.exe.out\", $\"FullIpcApp.exe {args[0]} {args[1]}\");\n\n            Console.WriteLine(\"Send initialization done message...\");\n            await yamsClient.SendInitializationDoneMessage();\n            Console.WriteLine(\"Initialization done message sent!\");\n\n            while (!exitMessageReceived)\n            {\n                await DoWork();\n                Console.WriteLine(\"Sending heart beat..\");\n                await yamsClient.SendHeartBeat();\n                Console.WriteLine(\"Heart beat sent!\");\n            }\n            await Shutdown();\n            Console.WriteLine(\"Exiting..\");\n        }\n\n        private static async Task Shutdown()\n        {\n            await Task.Delay(1000);\n        }\n\n        private static async Task DoWork()\n        {\n            Console.WriteLine(\"Doing work\");\n            await Task.Delay(1000);\n        }\n\n        private static Task Initialize()\n        {\n            return Task.Delay(1000);\n        }\n    }\n}"
  },
  {
    "path": "test/FullIpcProcess/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"FullIpcProcess\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"FullIpcProcess\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"99f3a36c-7930-4670-a8b3-7137d891671d\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/FullIpcProcess/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net452\" />\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"net452\" />\n  <package id=\"EnterpriseLibrary.TransientFaultHandling\" version=\"6.0.1304.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net452\" />\n  <package id=\"Rx-Core\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Interfaces\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Linq\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Main\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-PlatformServices\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net452\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime.Extensions\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime.InteropServices\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"System.Text.RegularExpressions\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net452\" />\n</packages>"
  },
  {
    "path": "test/GracefullShutdownProcess/GracefullShutdownProcess.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{706E37D7-B148-4734-9695-0D1AE6D4B3D5}</ProjectGuid>\n    <ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>GracefullShutdownProcess</RootNamespace>\n    <AssemblyName>GracefullShutdownProcess</AssemblyName>\n    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\bin\\Debug\\Data\\GracefullShutdownProcess\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\bin\\Release\\Data\\GracefullShutdownProcess\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\CommandLineParser.1.9.71\\lib\\net45\\CommandLine.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.ComponentModel.Composition\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Core.2.2.5\\lib\\net45\\System.Reactive.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Interfaces.2.2.5\\lib\\net45\\System.Reactive.Interfaces.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Linq.2.2.5\\lib\\net45\\System.Reactive.Linq.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-PlatformServices.2.2.5\\lib\\net45\\System.Reactive.PlatformServices.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Client\\Etg.Yams.Client.csproj\">\n      <Project>{d4624b9b-67a1-46d5-9468-58995b2720f9}</Project>\n      <Name>Etg.Yams.Client</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/GracefullShutdownProcess/Program.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Etg.Yams.Client;\nusing System.IO;\n\nnamespace GracefullShutdownProcess\n{\n    internal class Program\n    {\n        public static void Main(string[] args)\n        {\n            Run(args).Wait();\n        }\n\n        private static async Task Run(string[] args)\n        {\n            Console.WriteLine(\"args \" + string.Join(\" \", args));\n            int shutdownDelay = 1000 * Convert.ToInt32(args[2]);\n\n            var yamsClientConfig = new YamsClientConfigBuilder(args).Build();\n            var yamsClientFactory = new YamsClientFactory();\n\n            Console.WriteLine(\"Initializing...\");\n            IYamsClient yamsClient = yamsClientFactory.CreateYamsClient(yamsClientConfig);\n\n            await yamsClient.Connect();\n            Console.WriteLine(\"Initialization done!\");\n\n            bool exitMessageReceived = false;\n            yamsClient.ExitMessageReceived += (sender, eventArgs) =>\n            {\n                Console.WriteLine(\"Exit message received!\");\n                exitMessageReceived = true;\n            };\n\n            File.WriteAllText($\"GracefulShutdownApp.exe.out\", $\"GracefulShutdownApp.exe {args[0]} {args[1]}\");\n\n            while (!exitMessageReceived)\n            {\n                await Task.Delay(100);\n                Console.WriteLine(\"Doing work\");\n            }\n            await Task.Delay(shutdownDelay);\n            Console.WriteLine(\"Exiting..\");\n        }\n    }\n}"
  },
  {
    "path": "test/GracefullShutdownProcess/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n\n[assembly: AssemblyTitle(\"GracefullShutdownProcess\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"GracefullShutdownProcess\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n\n[assembly: Guid(\"706E37D7-B148-4734-9695-0D1AE6D4B3D5\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]"
  },
  {
    "path": "test/GracefullShutdownProcess/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.2\" /></startup>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.WindowsAzure.Storage\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-8.4.0.0\" newVersion=\"8.4.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>\n"
  },
  {
    "path": "test/GracefullShutdownProcess/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net452\" />\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"net452\" />\n  <package id=\"EnterpriseLibrary.TransientFaultHandling\" version=\"6.0.1304.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net452\" />\n  <package id=\"Rx-Core\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Interfaces\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Linq\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Main\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-PlatformServices\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net452\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime.Extensions\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime.InteropServices\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"System.Text.RegularExpressions\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net452\" />\n</packages>"
  },
  {
    "path": "test/HangingProcess/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" />\n    </startup>\n</configuration>"
  },
  {
    "path": "test/HangingProcess/HangingProcess.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{1DD27CAF-AC19-4674-A42B-F15260929BAF}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>HangingProcess</RootNamespace>\n    <AssemblyName>HangingProcess</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\Data\\Exes\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\Data\\Exes\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/HangingProcess/Program.cs",
    "content": "﻿using System;\n\nnamespace HangingProcess\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            Console.ReadLine();\n        }\n    }\n}\n"
  },
  {
    "path": "test/HangingProcess/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"HangingProcess\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"HangingProcess\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"1dd27caf-ac19-4674-a42b-f15260929baf\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/HeartBeatProcess/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.2\" />\n    </startup>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.WindowsAzure.Storage\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-8.4.0.0\" newVersion=\"8.4.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>"
  },
  {
    "path": "test/HeartBeatProcess/HeartBeatProcess.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{257044FB-F7A8-499D-8EF2-B5CAD76D617A}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>HeartBeatProcess</RootNamespace>\n    <AssemblyName>HeartBeatProcess</AssemblyName>\n    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\bin\\Debug\\Data\\HeartBeatProcess\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\bin\\Release\\Data\\HeartBeatProcess\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\CommandLineParser.1.9.71\\lib\\net45\\CommandLine.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.ComponentModel.Composition\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Core.2.2.5\\lib\\net45\\System.Reactive.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Interfaces.2.2.5\\lib\\net45\\System.Reactive.Interfaces.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Linq.2.2.5\\lib\\net45\\System.Reactive.Linq.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-PlatformServices.2.2.5\\lib\\net45\\System.Reactive.PlatformServices.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Client\\Etg.Yams.Client.csproj\">\n      <Project>{d4624b9b-67a1-46d5-9468-58995b2720f9}</Project>\n      <Name>Etg.Yams.Client</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/HeartBeatProcess/Program.cs",
    "content": "﻿using Etg.Yams.Client;\nusing System;\nusing System.IO;\nusing System.Threading.Tasks;\n\nnamespace HeartBeatProcess\n{\n    internal class Program\n    {\n        public static void Main(string[] args)\n        {\n            Run(args).Wait();\n        }\n\n        private static async Task Run(string[] args)\n        {\n            Console.WriteLine(\"args \" + string.Join(\" \", args));\n            var heartBeatPeriod = TimeSpan.FromSeconds(Convert.ToInt32(args[2]));\n\n            var yamsClientConfig = new YamsClientConfigBuilder(args).Build();\n            var yamsClientFactory = new YamsClientFactory();\n\n            Console.WriteLine(\"Initializing...\");\n            IYamsClient yamsClient = yamsClientFactory.CreateYamsClient(yamsClientConfig);\n\n            await yamsClient.Connect();\n\n            File.WriteAllText($\"HeartBeatApp.exe.out\", $\"HeartBeatApp.exe {args[0]} {args[1]}\");\n\n            while (true)\n            {\n                await Task.Delay(heartBeatPeriod);\n                Console.WriteLine(\"Sending heart beat..\");\n                await yamsClient.SendHeartBeat();\n                Console.WriteLine(\"Heart beat sent!\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "test/HeartBeatProcess/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"HeartBeatProcess\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"HeartBeatProcess\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"257044fb-f7a8-499d-8ef2-b5cad76d617a\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/HeartBeatProcess/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net452\" />\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"net452\" />\n  <package id=\"EnterpriseLibrary.TransientFaultHandling\" version=\"6.0.1304.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net452\" />\n  <package id=\"Rx-Core\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Interfaces\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Linq\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Main\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-PlatformServices\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net452\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime.Extensions\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime.InteropServices\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"System.Text.RegularExpressions\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net452\" />\n</packages>"
  },
  {
    "path": "test/MonitorInitProcess/MonitorInitProcess.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{BB84CC4C-EB11-4A61-8ED4-791EADAA46E1}</ProjectGuid>\n    <ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>MonitorInitProcess</RootNamespace>\n    <AssemblyName>MonitorInitProcess</AssemblyName>\n    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\bin\\Debug\\Data\\MonitorInitProcess\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\bin\\Release\\Data\\MonitorInitProcess\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Autofac.3.5.2\\lib\\net40\\Autofac.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\CommandLineParser.1.9.71\\lib\\net45\\CommandLine.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\\lib\\portable-net45+win+wp8\\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.ComponentModel.Composition\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Core.2.2.5\\lib\\net45\\System.Reactive.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Interfaces.2.2.5\\lib\\net45\\System.Reactive.Interfaces.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-Linq.2.2.5\\lib\\net45\\System.Reactive.Linq.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Rx-PlatformServices.2.2.5\\lib\\net45\\System.Reactive.PlatformServices.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Client\\Etg.Yams.Client.csproj\">\n      <Project>{d4624b9b-67a1-46d5-9468-58995b2720f9}</Project>\n      <Name>Etg.Yams.Client</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/MonitorInitProcess/Program.cs",
    "content": "﻿using Etg.Yams.Client;\nusing System;\nusing System.IO;\nusing System.Threading.Tasks;\n\nnamespace MonitorInitProcess\n{\n    internal class Program\n    {\n        public static void Main(string[] args)\n        {\n            Run(args).Wait();\n        }\n\n        private static async Task Run(string[] args)\n        {\n            Console.WriteLine(\"args \" + string.Join(\" \", args));\n            var yamsClientConfig = new YamsClientConfigBuilder(args).Build();\n            var yamsClientFactory = new YamsClientFactory();\n\n            Console.WriteLine(\"Initializing...\");\n            IYamsClient yamsClient = yamsClientFactory.CreateYamsClient(yamsClientConfig);\n\n            Task initTimeMax = Task.Delay(1000*Convert.ToInt32(args[2]));\n\n            File.WriteAllText($\"MonitorInitApp.exe.out\", $\"MonitorInitApp.exe {args[0]} {args[1]}\");\n\n            await Task.WhenAll(yamsClient.Connect(), Task.Delay(TimeSpan.FromSeconds(5)), initTimeMax);\n\n            Console.WriteLine(\"Send initialization done message...\");\n            await yamsClient.SendInitializationDoneMessage();\n            Console.WriteLine(\"Initialization done message sent!\");\n\n            while (true)\n            {\n                await Task.Delay(1000);\n                Console.WriteLine(\"Doing work\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "test/MonitorInitProcess/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n\n[assembly: AssemblyTitle(\"MonitorInitProcess\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"MonitorInitProcess\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n\n[assembly: Guid(\"BB84CC4C-EB11-4A61-8ED4-791EADAA46E1\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]"
  },
  {
    "path": "test/MonitorInitProcess/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.2\" /></startup>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.WindowsAzure.Storage\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-8.4.0.0\" newVersion=\"8.4.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>\n"
  },
  {
    "path": "test/MonitorInitProcess/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Autofac\" version=\"3.5.2\" targetFramework=\"net452\" />\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"net452\" />\n  <package id=\"EnterpriseLibrary.TransientFaultHandling\" version=\"6.0.1304.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net452\" />\n  <package id=\"Rx-Core\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Interfaces\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Linq\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-Main\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Rx-PlatformServices\" version=\"2.2.5\" targetFramework=\"net452\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net452\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime.Extensions\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Runtime.InteropServices\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"System.Text.RegularExpressions\" version=\"4.1.0\" targetFramework=\"net452\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net452\" />\n</packages>"
  },
  {
    "path": "test/Stubs/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Stubs\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Stubs\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"68cd41f8-a6c3-4d43-93ca-92e898254cbd\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/Stubs/SimpleStubs.json",
    "content": "{\n    \"IgnoredProjects\": [\n    ],\n    \"IgnoredInterfaces\": [\n    ],\n\t\"StubInternalInterfaces\": false\n}"
  },
  {
    "path": "test/Stubs/Stubs.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{68CD41F8-A6C3-4D43-93CA-92E898254CBD}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Stubs</RootNamespace>\n    <AssemblyName>Stubs</AssemblyName>\n    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <NuGetPackageImportStamp>\n    </NuGetPackageImportStamp>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\CommandLineParser.1.9.71\\lib\\net45\\CommandLine.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Etg.SimpleStubs, Version=0.0.1.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Etg.SimpleStubs.2.3.1\\lib\\dotnet50\\Etg.SimpleStubs.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Azure.KeyVault.Core.1.0.0\\lib\\net40\\Microsoft.Azure.KeyVault.Core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Edm.5.8.2\\lib\\net40\\Microsoft.Data.Edm.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.OData.5.8.2\\lib\\net40\\Microsoft.Data.OData.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Microsoft.Data.Services.Client.5.8.2\\lib\\net40\\Microsoft.Data.Services.Client.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\WindowsAzure.Storage.8.4.0\\lib\\net45\\Microsoft.WindowsAzure.Storage.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Newtonsoft.Json.6.0.8\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\Semver.2.0.4\\lib\\net452\\Semver.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\System.Spatial.5.8.2\\lib\\net40\\System.Spatial.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Properties\\SimpleStubs.generated.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n    <None Include=\"SimpleStubs.json\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\AzureBlobStorageUpdateSession\\AzureBlobStorageUpdateSession.csproj\">\n      <Project>{894b7986-5aa4-42a7-8eb0-6dfd1f604505}</Project>\n      <Name>AzureBlobStorageUpdateSession</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\AzureUtils\\AzureUtils.csproj\">\n      <Project>{1c890e49-5a9b-4eab-9f69-6a6e78d82610}</Project>\n      <Name>AzureUtils</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Client\\Etg.Yams.Client.csproj\">\n      <Project>{d4624b9b-67a1-46d5-9468-58995b2720f9}</Project>\n      <Name>Etg.Yams.Client</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Core\\Etg.Yams.Core.csproj\">\n      <Project>{7145e485-34fa-4632-89b0-bd27c96af69c}</Project>\n      <Name>Etg.Yams.Core</Name>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\src\\Etg.Yams.Ipc\\Etg.Yams.Ipc.csproj\">\n      <Project>{c7c03d37-f2d2-4115-8423-86c1bf1b8a18}</Project>\n      <Name>Etg.Yams.Ipc</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <Import Project=\"..\\..\\packages\\Etg.SimpleStubs.2.3.1\\build\\Etg.SimpleStubs.targets\" Condition=\"Exists('..\\..\\packages\\Etg.SimpleStubs.2.3.1\\build\\Etg.SimpleStubs.targets')\" />\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\..\\packages\\Etg.SimpleStubs.2.3.1\\build\\Etg.SimpleStubs.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\packages\\Etg.SimpleStubs.2.3.1\\build\\Etg.SimpleStubs.targets'))\" />\n  </Target>\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/Stubs/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"net452\" />\n  <package id=\"Etg.SimpleStubs\" version=\"2.3.1\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Azure.KeyVault.Core\" version=\"1.0.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Edm\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.OData\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Data.Services.Client\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"Newtonsoft.Json\" version=\"6.0.8\" targetFramework=\"net452\" />\n  <package id=\"Semver\" version=\"2.0.4\" targetFramework=\"net452\" />\n  <package id=\"System.ComponentModel.EventBasedAsync\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Dynamic.Runtime\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Linq.Queryable\" version=\"4.0.0\" targetFramework=\"net452\" />\n  <package id=\"System.Net.Requests\" version=\"4.0.11\" targetFramework=\"net452\" />\n  <package id=\"System.Spatial\" version=\"5.8.2\" targetFramework=\"net452\" />\n  <package id=\"WindowsAzure.Storage\" version=\"8.4.0\" targetFramework=\"net452\" />\n</packages>"
  },
  {
    "path": "test/SuicidalProcess/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" />\n    </startup>\n</configuration>"
  },
  {
    "path": "test/SuicidalProcess/Program.cs",
    "content": "﻿namespace SuicidalProcess\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/SuicidalProcess/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"SuicidalProcess\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"SuicidalProcess\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"80a3b3bd-8d2f-471a-a198-576772faa048\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/SuicidalProcess/SuicidalProcess.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{80A3B3BD-8D2F-471A-A198-576772FAA048}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>SuicidalProcess</RootNamespace>\n    <AssemblyName>SuicidalProcess</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\Data\\Exes\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\Data\\Exes\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/TestProcess/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.1\" />\n    </startup>\n</configuration>"
  },
  {
    "path": "test/TestProcess/Program.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Reflection;\n\nnamespace TestProcess\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            new Program().Run(args);\n        }\n\n        private void Run(string[] args)\n        {\n            string codeBase = Assembly.GetExecutingAssembly().CodeBase;\n            string exeName = Path.GetFileName(codeBase);\n\n            File.WriteAllText($\"{exeName}.out\", $\"{exeName} \" + string.Join(\" \", args));\n\n            Console.ReadLine();\n        }\n    }\n}\n"
  },
  {
    "path": "test/TestProcess/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"TestProcess\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"TestProcess\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"aeaee225-1080-4cc9-8ba8-9f7580ed1b9b\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/TestProcess/TestProcess.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{AEAEE225-1080-4CC9-8BA8-9F7580ED1B9B}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>TestProcess</RootNamespace>\n    <AssemblyName>TestProcess</AssemblyName>\n    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\Data\\Exes\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>..\\Etg.Yams.Core.Test\\Data\\Exes\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/TestUtils/AssertUtils.cs",
    "content": "﻿using System.Collections.Generic;\nusing Xunit;\n\nnamespace Etg.Yams.TestUtils\n{\n    public static class AssertUtils\n    {\n        public static void ContainsSameElementsInAnyOrder<T>(IEnumerable<T> expected, IEnumerable<T> actual)\n        {\n            Assert.True(new HashSet<T>(expected).SetEquals(actual),\n                \"The two enumerables do not contain the same set of elements\");\n        }\n    }\n}"
  },
  {
    "path": "test/TestUtils/AsyncUtils.cs",
    "content": "﻿// -------------------------------------------------------------------\n// Copyright (c) Microsoft Corporation. All Rights Reserved.\n// -------------------------------------------------------------------\n\nusing System;\nusing System.Threading.Tasks;\n\nnamespace Etg.Yams.TestUtils\n{\n    public class AsyncUtils\n    {\n        public static Task<TReturnType> AsyncTaskThatThrows<TReturnType>(Exception exception)\n        {\n            TaskCompletionSource<TReturnType> tcs = new TaskCompletionSource<TReturnType>();\n            tcs.SetException(exception);\n            return tcs.Task;\n        }\n\n        public static Task AsyncTaskThatThrows(Exception exception)\n        {\n            return AsyncTaskThatThrows<bool>(exception);\n        }\n\n        public static Task<TReturnType> AsyncTaskWithResult<TReturnType>(TReturnType result)\n        {\n            TaskCompletionSource<TReturnType> tcs = new TaskCompletionSource<TReturnType>();\n            tcs.SetResult(result);\n            return tcs.Task;\n        }\n    }\n}"
  },
  {
    "path": "test/TestUtils/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"TestUtils\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"TestUtils\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"c25452e1-aff2-4579-b6b4-f040cad02fda\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "test/TestUtils/TestUtils.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{C25452E1-AFF2-4579-B6B4-F040CAD02FDA}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Etg.Yams.TestUtils</RootNamespace>\n    <AssemblyName>TestUtils</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n    <Reference Include=\"xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.abstractions.2.0.0\\lib\\net35\\xunit.abstractions.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.assert, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.assert.2.1.0\\lib\\dotnet\\xunit.assert.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.core, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.core.2.1.0\\lib\\dotnet\\xunit.core.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"xunit.execution.desktop, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL\">\n      <HintPath>..\\..\\packages\\xunit.extensibility.execution.2.1.0\\lib\\net45\\xunit.execution.desktop.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"AssertUtils.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"AsyncUtils.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "test/TestUtils/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"xunit\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.abstractions\" version=\"2.0.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.assert\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.core\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.extensibility.core\" version=\"2.1.0\" targetFramework=\"net45\" />\n  <package id=\"xunit.extensibility.execution\" version=\"2.1.0\" targetFramework=\"net45\" />\n</packages>"
  }
]