Highlight when margin requirements above normal levels

--- rh-cli/Program.cs
+++ rh-cli/Program.cs
@@ -176,7 +176,18 @@

             Display_PriceChange(qqq.LastTradePrice, qqq.PreviousClose);

-            Console.WriteLine("Initial / Maintainence Margin Requirement: {0} / {1}", instrument.MarginInitialRatio.ToString("P"), instrument.MaintenanceRatio.ToString("P"));
+            Console.Write("Initial / Maintainence Margin Requirement: ");
+
+            if (instrument.MarginInitialRatio > 0.5m)
+                Console.ForegroundColor = ConsoleColor.Yellow;
+            Console.Write(instrument.MarginInitialRatio.ToString("P"));
+            Console.ResetColor();
+            Console.Write(" / ");
+
+            if (instrument.MaintenanceRatio > 0.25m)
+                Console.ForegroundColor = ConsoleColor.Yellow;
+            Console.WriteLine(instrument.MaintenanceRatio.ToString("P"));
+            Console.ResetColor();

             if (!instrument.IsTradeable)
             {


Enhance avoidalias setproperty method

Enhance avoidalias setproperty method

--- Rules/AvoidAlias.cs
+++ Rules/AvoidAlias.cs
@@ -62,11 +62,31 @@
                 return;
             }
             IEnumerable<string> aliases = obj as IEnumerable<string>;
-            if (obj == null)
-            {
-                return;
-            }
-            whiteList.AddRange(aliases);
+            if (aliases == null)
+            {
+                // try with enumerable objects
+                var enumerableObjs = obj as IEnumerable<object>;
+                if (enumerableObjs == null)
+                {
+                    return;
+                }
+                foreach (var x in enumerableObjs)
+                {
+                    var y = x as string;
+                    if (y == null)
+                    {
+                        return;
+                    }
+                    else
+                    {
+                        whiteList.Add(y);
+                    }
+                }
+            }
+            else
+            {
+                whiteList.AddRange(aliases);
+            }
         }

         /// <summary>


client unit tests

client unit tests

--- test/CacheCow.Client.Tests/CachingHandlerTests.cs
+++ test/CacheCow.Client.Tests/CachingHandlerTests.cs
@@ -436,7 +436,53 @@

 		}

-
+        [Fact]
+        public void Delete_Validate_Etag()
+        {
+            // setup
+            var request = new HttpRequestMessage(HttpMethod.Delete, DummyUrl);
+            var responseFromCache = GetOkMessage(true);
+            responseFromCache.Headers.ETag = new EntityTagHeaderValue(ETagValue);
+            var responseFromServer = new HttpResponseMessage(HttpStatusCode.NotModified);
+            _messageHandler.Response = responseFromServer;
+            _cacheStore.Setup(x => x.GetValueAsync(It.IsAny<CacheKey>())).ReturnsAsync(responseFromCache);
+
+            // run
+            var task = _client.SendAsync(request);
+            var responseReturned = task.Result;
+
+            // verify
+            Assert.Equal(ETagValue, request.Headers.IfMatch.First().Tag);
+            Assert.Equal(responseFromServer, responseReturned);
+
+        }
+
+        [Fact]
+        public void Delete_Validate_Expires()
+        {
+            // setup
+            var request = new HttpRequestMessage(HttpMethod.Delete, DummyUrl);
+            var lastModified = DateTimeOffset.UtcNow.AddHours(-1);
+            lastModified = lastModified.AddMilliseconds(1000 - lastModified.Millisecond);
+            var responseFromCache = GetOkMessage(true);
+            responseFromCache.Content.Headers.LastModified = lastModified;
+            var responseFromServer = GetOkMessage();
+            _messageHandler.Response = responseFromServer;
+            _cacheStore.Setup(x => x.GetValueAsync(It.IsAny<CacheKey>())).ReturnsAsync(responseFromCache);
+
+
+
+            // run
+            var task = _client.SendAsync(request);
+            var responseReturned = task.Result;
+
+            // verify
+            Assert.Equal(lastModified.ToString(), request.Headers.IfUnmodifiedSince.Value.ToString());
+            Assert.Equal(responseFromServer, responseReturned);
+
+        }
+
+
         [Fact]
 	    public void DoesNotDisposeCacheStoreIfPassedToIt()
         {


Build warnings for Assert.NotNull on KeyValuePair in TracerTests  (#594)

* Changing implementation from NotNull to Equals based on the value

* Update test/OpenTelemetry.Tests/Impl/Trace/TracerTest.cs

Co-Authored-By: Bruno Garcia <660609b171607ff3dcd294929e5d8239736f4298@brunogarcia.com>

* Apply suggestions from code review

Co-Authored-By: Mike Goldsmith <c43a3c67d7a1203c37ce25b098df0254011e1ce6@gmail.com>

* Apply suggestions from code review

Co-Authored-By: Mike Goldsmith <c43a3c67d7a1203c37ce25b098df0254011e1ce6@gmail.com>

Co-authored-by: Bruno Garcia <660609b171607ff3dcd294929e5d8239736f4298@brunogarcia.com>
Co-authored-by: Mike Goldsmith <c43a3c67d7a1203c37ce25b098df0254011e1ce6@gmail.com>
Co-authored-by: Sergey Kanzhelev <dd2a78e617335ac05535a01af404ce3eb19c30fd@live.com>

--- test/OpenTelemetry.Tests/Impl/Trace/TracerTest.cs
+++ test/OpenTelemetry.Tests/Impl/Trace/TracerTest.cs
@@ -410,8 +410,8 @@

             Assert.NotNull(span);

-            Assert.NotNull(span.Attributes.FirstOrDefault(k => k.Key == "key1"));
-            Assert.NotNull(span.Attributes.FirstOrDefault(k => k.Key == "key2"));
+            Assert.Single(span.Attributes.Where(k => k.Key == "key1" && k.Value == "value1"));
+            Assert.Single(span.Attributes.Where(k => k.Key == "key2" && k.Value == "value2"));
         }
     }
 }


エラーをわかりやすくしました。

エラーをわかりやすくしました。

--- Sdx/Db/RecordSet.cs
+++ Sdx/Db/RecordSet.cs
@@ -62,7 +62,13 @@
       var exists = true;
       foreach(var column in pkeys)
       {
-        if (row[Record.BuildColumnAliasWithContextName(column.Name, contextName)] is DBNull)
+        var rowKey = Record.BuildColumnAliasWithContextName(column.Name, contextName);
+        if (!row.ContainsKey(rowKey))
+        {
+          throw new InvalidOperationException("Missing " + rowKey + " in " + Sdx.Diagnostics.Debug.Dump(row));
+        }
+
+        if (row[rowKey] is DBNull)
         {
           exists = false;
           break;


Updated assembly info (product version).

--- tibiaapi/Properties/AssemblyInfo.cs
+++ tibiaapi/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@
 //      Build Number
 //      Revision
 //
-[assembly: AssemblyVersion("2.9.9.0")]
-[assembly: AssemblyFileVersion("2.9.9.0")]
+[assembly: AssemblyVersion("2.9.10.0")]
+[assembly: AssemblyFileVersion("2.9.10.0")]


Fixed #166

Fixed #166

--- src/libvideo/YouTube.cs
+++ src/libvideo/YouTube.cs
@@ -62,7 +62,6 @@

         private IEnumerable<YouTubeVideo> ParseVideos(string source)
         {
-            string title = Html.GetNode("title", source);
             IEnumerable<UnscrambledQuery> queries;
             string jsPlayer = ParseJsPlayer(source);
             if (jsPlayer == null)
@@ -79,6 +78,7 @@
             if (string.IsNullOrWhiteSpace(errorReason))
             {
                 var isLiveStream = playerResponseJson.SelectToken("videoDetails.isLive")?.Value<bool>() == true;
+                string title = playerResponseJson.SelectToken("videoDetails.title")?.Value<string>();
                 if (isLiveStream)
                 {
                     throw new UnavailableStreamException($"This is live stream so unavailable stream.");


Use Context.Tools for tool resolution.

Use Context.Tools for tool resolution.

--- build.cake
+++ build.cake
@@ -151,10 +151,11 @@

 		string filter = string.Concat(coverageAssemblies.Select(x => $@" ""-filter:+[{x}]*"""));

+		var nunitPath = Context.Tools.Resolve("nunit3-console.exe").ToString();
 		foreach (var testDllPath in GetFiles($"tests/**/bin/**/*.UnitTests.dll"))
 		{
-			ExecuteProcess(@"cake\OpenCover\tools\OpenCover.Console.exe",
-				$@"-register:user -mergeoutput ""-target:cake\NUnit.ConsoleRunner\tools\nunit3-console.exe"" ""-targetargs:{testDllPath} --noresult"" ""-output:release\coverage.xml"" -skipautoprops -returntargetcode" + filter);
+			ExecuteTool("OpenCover.Console.exe",
+				$@"-register:user -mergeoutput ""-target:{nunitPath}"" ""-targetargs:{testDllPath} --noresult"" ""-output:{File("release/coverage.xml")}"" -skipautoprops -returntargetcode" + filter);
 		}
 	});

@@ -162,14 +163,14 @@
 	.IsDependentOn("Coverage")
 	.Does(() =>
 	{
-		ExecuteProcess(@"cake\ReportGenerator\tools\ReportGenerator.exe", $@"""-reports:release\coverage.xml"" ""-targetdir:release\coverage""");
+		ExecuteTool("ReportGenerator.exe", $@"""-reports:{File("release/coverage.xml")}"" ""-targetdir:{File("release/coverage")}""");
 	});

 Task("CoveragePublish")
 	.IsDependentOn("Coverage")
 	.Does(() =>
 	{
-		ExecuteProcess(@"cake\coveralls.io\tools\coveralls.net.exe", $@"--opencover ""release\coverage.xml"" --full-sources --repo-token {coverallsApiKey}");
+		ExecuteTool("coveralls.net.exe", $@"--opencover ""{File("release/coverage.xml")}"" --full-sources --repo-token {coverallsApiKey}");
 	});

 Task("Default")
@@ -206,6 +207,11 @@
 		throw new InvalidOperationException($"Code generation failed with exit code {exitCode}.");
 }

+void ExecuteTool(string tool, string arguments)
+{
+	ExecuteProcess(Context.Tools.Resolve(tool).ToString(), arguments);
+}
+
 void ExecuteProcess(string exePath, string arguments)
 {
 	if (IsRunningOnUnix())


Add criteria to Slack task

Add criteria to Slack task


Update build.cake

Update build.cake

--- build.cake
+++ build.cake
@@ -58,7 +58,7 @@
 var releaseNuGetApiKey = EnvironmentVariable("NuGetApiKey");
 var unstableNuGetSource = "https://www.myget.org/F/wekempf/api/v2/package";
 var unstableNuGetApiKey = EnvironmentVariable("MyGetApiKey");
-var gitPagesRepo = "git@github.com:wekempf/testify.git";
+var gitPagesRepo = "https://wekempf:" + EnvironmentVariable("GitHubPersonalAccessToken") + "@github.com/wekempf/testify.git";
 var gitPagesBranch = "gh-pages";
 var branch = EnvironmentVariable("APPVEYOR_REPO_BRANCH") ?? GitBranchCurrent(".").FriendlyName;
 Information("Branch: " + branch);


Test of package 2

Test of package 2

--- build.cake
+++ build.cake
@@ -89,7 +89,7 @@

 Task("Default")
-    .IsDependentOn("Package");
+    .IsDependentOn("Publish");

 RunTarget(target);


Update build.cake

Update build.cake

[skip ci]

--- build.cake
+++ build.cake
@@ -117,8 +117,8 @@
 {
     Id = "WavFile",
     Version = version,
-    Authors = new [] { "wieslaw.soltes" },
-    Owners = new [] { "wieslaw.soltes" },
+    Authors = new [] { "wieslawsoltes" },
+    Owners = new [] { "wieslawsoltes" },
     LicenseUrl = new Uri("http://opensource.org/licenses/MIT"),
     ProjectUrl = new Uri("https://github.com/wieslawsoltes/SimpleWavSplitter/"),
     RequireLicenseAcceptance = false,
@@ -159,8 +159,8 @@

 var SetChocolateyNuspecCommonProperties = new Action<ChocolateyPackSettings> ((nuspec) => {
     nuspec.Version = version;
-    nuspec.Authors = new [] { "wieslaw.soltes" };
-    nuspec.Owners = new [] { "wieslaw.soltes" };
+    nuspec.Authors = new [] { "wieslawsoltes" };
+    nuspec.Owners = new [] { "wieslawsoltes" };
     nuspec.LicenseUrl = new Uri("http://opensource.org/licenses/MIT");
     nuspec.ProjectUrl = new Uri("https://github.com/wieslawsoltes/SimpleWavSplitter/");
     nuspec.PackageSourceUrl = new Uri("https://github.com/wieslawsoltes/SimpleWavSplitter/");


Upload test output as artifact

Upload test output as artifact

--- build.cake
+++ build.cake
@@ -46,6 +46,7 @@
 var FILE_SOLUTIONINFO = System.IO.Path.Combine(PROJECT_DIR, "Source", "SolutionInfo.cs");
 var FILE_OPENCOVER_REPORT = System.IO.Path.Combine(DIR_OUTPUT_REPORTS, "opencover-results.xml");
 var FILE_NUNIT_XML_REPORT = System.IO.Path.Combine(DIR_OUTPUT_REPORTS, "nunit-results.xml");
+var FILE_NUNIT_TXT_REPORT = System.IO.Path.Combine(DIR_OUTPUT_REPORTS, "nunit-output.txt");
 var FILE_DOCUMENTATION_MAKE = System.IO.Path.Combine(DIR_DOCUMENTATION, "make.bat");
 var FILE_OUTPUT_DOCUMENTATION_ZIP = System.IO.Path.Combine(
     DIR_OUTPUT_DOCUMENTATION,
@@ -107,7 +108,11 @@
 // =====================================================================================================
 Task("Test")
     .IsDependentOn("Build")
-    .Finally(() => UploadTestResults(FILE_NUNIT_XML_REPORT))
+    .Finally(() =>
+        {
+            UploadArtifact(FILE_NUNIT_TXT_REPORT);
+            UploadTestResults(FILE_NUNIT_XML_REPORT);
+        })
     .Does(() =>
         {
             ExecuteTest("./Source/**/bin/" + CONFIGURATION + "/EventFlow*Tests.dll", FILE_NUNIT_XML_REPORT);
@@ -181,6 +186,12 @@

 void UploadArtifact(string filePath)
 {
+    if (!FileExists(filePath))
+    {
+        Information("Skipping uploading of artifact, does not exist: {0}", filePath);
+        return;
+    }
+
     if (AppVeyor.IsRunningOnAppVeyor)
     {
         Information("Uploading artifact: {0}", filePath);
@@ -195,6 +206,12 @@

 void UploadTestResults(string filePath)
 {
+    if (!FileExists(filePath))
+    {
+        Information("Skipping uploading of test results, does not exist: {0}", filePath);
+        return;
+    }
+
     if (AppVeyor.IsRunningOnAppVeyor)
     {
         Information("Uploading test results: {0}", filePath);
@@ -281,7 +298,7 @@
                         NoColor = true,
                         Framework = "net-4.5",
                         ToolPath = TOOL_NUNIT,
-                        //OutputFile = nunitOutputPath,
+                        OutputFile = FILE_NUNIT_TXT_REPORT,
                         Results = resultsFile,
                         DisposeRunners = true
                     });


Windows test works with global cake

Windows test works with global cake

--- build.cake
+++ build.cake
@@ -112,7 +112,7 @@
         // *************************************************/
         DotNetNew("caketest", testSln);
         //Test "publish" task
-        RunCakeScript(testSln, @"build.ps1", "-Target publish");
+        RunCakeScript(testSln, "--target=publish");
         var outputDll = System.IO.Path.Combine(testSln, "artifacts", "CakeTest.Console", "CakeTest.Console.dll");
         if(!System.IO.File.Exists(outputDll))
             throw new Exception($"\"Publish\" task of template failed. Could not find {outputDll}");
@@ -120,7 +120,7 @@
             Information("\"Publish\" task of template ran successfully");

         // Test "pack" task
-        RunCakeScript(testSln, @"build.ps1", "-Target pack");
+        RunCakeScript(testSln, "--target=pack");
         var outputPackage = System.IO.Path.Combine(testSln, "artifacts", "CakeTest.Console.0.0.0.nupkg");
         if(!System.IO.File.Exists(outputPackage))
             throw new Exception($"\"Pack\" task of template failed. Could not find {outputPackage}");
@@ -130,7 +130,7 @@
         /************************************************
         *        Test Docker Container build task
         *************************************************/
-        RunCakeScript(testSln, @"build.ps1", "-Target Build-Container");
+        RunCakeScript(testSln, "--target=Build-Container");
         DockerRmi(new string[] {"local/caketest", "local/caketest:0.0.0-0"});

         /************************************************
@@ -181,16 +181,16 @@
 		Information("To push the NuGet template to nuget.org use: -Target Push --apiKey=\"your nuget api key\"");
 	});

-void RunCakeScript(string workDir, string script, string arguments)
-{
-    var cakeArgs = $"\"{System.IO.Path.Combine(workDir, script)} {arguments}\"";
+void RunCakeScript(string workDir, string arguments)
+{
+    arguments = $"cake --verbosity=verbose {arguments}";
     using(var process = StartAndReturnProcess(
-        "dotnet cake",
-        new ProcessSettings{ Arguments = cakeArgs, WorkingDirectory = workDir }))
-    {
-        process.WaitForExit();
-        // This should output 0 as valid arguments supplied
-        Information($"Run \"dotnet cake {cakeArgs}\" with Exit code: {process.GetExitCode()}");
+        "dotnet",
+        new ProcessSettings{ Arguments = arguments, WorkingDirectory = workDir }))
+    {
+        process.WaitForExit();
+        // This should output 0 as valid arguments supplied
+        Information($"Run \"dotnet cake {arguments}\" with Exit code: {process.GetExitCode()}");
     }
 }


removed versioning from build.cake

removed versioning from build.cake

--- build.cake
+++ build.cake
@@ -1,7 +1,8 @@
 #tool nuget:?package=NUnit.ConsoleRunner&version=3.11.1
 #tool nuget:?package=OpenCover&version=4.7.922
-#tool nuget:?package=ReportGenerator&version=4.5.5
-
+#tool nuget:?package=ReportGenerator&version=4.5.6
+
+#addin nuget:?package=Cake.GitVersioning&version=3.1.91
 #addin nuget:?package=Cake.Incubator&version=5.1.0

 using Cake.Core;
@@ -80,14 +81,11 @@
 Task("UpdateAssemblyInfo")
     .Does(() =>
     {
+        var gitVersionInformation = GitVersioningGetVersion();
         var assemblyInfoParseResult = ParseAssemblyInfo(AssemblyInfoPath);

         var settings = new AssemblyInfoSettings()
         {
-            Version                 = assemblyInfoParseResult.AssemblyVersion,
-            FileVersion             = assemblyInfoParseResult.AssemblyFileVersion,
-            InformationalVersion    = assemblyInfoParseResult.AssemblyInformationalVersion,
-
             Product                 = assemblyInfoParseResult.Product,
             Company                 = assemblyInfoParseResult.Company,
             Trademark               = assemblyInfoParseResult.Trademark,
@@ -107,67 +105,21 @@
                     Key = "Compiled on:",
                     Value = "[UTC]" + DateTime.UtcNow.ToString(),
                 },
+                new AssemblyInfoMetadataAttribute()
+                {
+                    Key = "Commit date:",
+                    Value = gitVersionInformation.GitCommitDate?.ToString(),
+                },
             }
         };

-        if (BuildSystem.IsLocalBuild)
-        {
-            settings.Version                 = Increase(settings.Version);
-            settings.FileVersion             = Increase(settings.FileVersion);
-            settings.InformationalVersion    = Increase(settings.InformationalVersion);
-        }
-        else
-        {
-            if(BuildSystem.IsRunningOnAzurePipelinesHosted)
-            {
-                var build = int.Parse(EnvironmentVariable("BUILD_BUILDNUMBER") ?? "no version found from AzurePipelinesHosted");
-                settings.Version                 = IncreaseWith(settings.Version, build);
-                settings.FileVersion             = IncreaseWith(settings.FileVersion, build);
-                settings.InformationalVersion    = IncreaseWith(settings.InformationalVersion, build);
-
-                Information($"Version: {settings.Version}");
-                Information($"FileVersion: {settings.FileVersion}");
-                Information($"InformationalVersion: {settings.InformationalVersion}");
-            }
-            else
-            {
-                var version = EnvironmentVariable("APPVEYOR_BUILD_VERSION") ?? "no version found from AppVeyorEnvironment";
-                settings.Version                 = version;
-                settings.FileVersion             = version;
-                settings.InformationalVersion    = version;
-
-                Information($"Version: {version}");
-            }
-        }
-
         CreateAssemblyInfo(new FilePath(AssemblyInfoPath), settings);
-
-        string Increase(string data)
-        {
-            var version = new Version(data);
-            return new Version(version.Major,version.Minor,version.Build+1, version.Revision).ToString();
-        }
-
-        string IncreaseWith(string data, int build)
-        {
-            var version = new Version(data);
-            return new Version(version.Major,version.Minor,build, version.Revision).ToString();
-        }
 });

 Task("Build")
     .Does(()=>
     {
-        var version = string.Empty;
-        if (BuildSystem.AppVeyor.IsRunningOnAppVeyor)
-        {
-            version = EnvironmentVariable("APPVEYOR_BUILD_VERSION") ?? "no version found from AppVeyorEnvironment";
-        }
-        else
-        {
-            var assemblyInfoParseResult = ParseAssemblyInfo(AssemblyInfoPath);
-            version = assemblyInfoParseResult.AssemblyVersion;
-        }
+        var version = GitVersioningGetVersion().SemVer2;

         BuildAndPack(@".\src\MvvmScarletToolkit.Abstractions\MvvmScarletToolkit.Abstractions.csproj");
         BuildAndPack(@".\src\MvvmScarletToolkit\MvvmScarletToolkit.csproj");


Added GitLink

Added GitLink

--- build.cake
+++ build.cake
@@ -1,4 +1,5 @@
 #tool nuget:?package=NUnit.ConsoleRunner&version=3.7.0
+#tool GitLink

 //////////////////////////////////////////////////////////////////////
 // ARGUMENTS
@@ -319,9 +320,17 @@
         }
     });

+Task("GitLink")
+    .IsDependentOn("CreateImage")
+    .Description("Source-indexes PDBs in the images directory to the current commit")
+    .Does(() =>
+    {
+        GitLink3(GetFiles($"{CurrentImageDir}**/*.pdb"));
+    });
+
 Task("PackageFramework")
     .Description("Creates NuGet packages of the framework")
-    .IsDependentOn("CreateImage")
+    .IsDependentOn("GitLink")
     .Does(() =>
     {
         CreateDirectory(PACKAGE_DIR);
@@ -339,7 +348,7 @@

 Task("PackageZip")
     .Description("Creates a ZIP file of the framework")
-    .IsDependentOn("CreateImage")
+    .IsDependentOn("GitLink")
     .Does(() =>
     {
         CreateDirectory(PACKAGE_DIR);


update sonarbegin

update sonarbegin

--- build.cake
+++ build.cake
@@ -264,7 +264,7 @@
   .Does(() => {
     var coverageFilePath = MakeAbsolute(new FilePath(testCoverageOutputFile)).FullPath;
     Information("Sonar: Test Coverage Output File: " + testCoverageOutputFile);
-    var arguments = "sonarscanner begin /k:\"" + sonarqubeProjectKey + "\" /v:\"" + nugetVersion + "\" /d:\"sonar.host.url=https://sonarcloud.io\" /d:\"sonar.organization=" + sonarqubeOrganisationKey + "\" /d:\"sonar.login=" + sonarQubeLogin + "\" /d:sonar.cs.opencover.reportsPaths=\"" + coverageFilePath + "\"";
+    var arguments = "sonarscanner begin /k:\"" + sonarqubeProjectKey + "\" /v:\"" + nugetVersion + "\" /d:\"sonar.host.url=https://sonarcloud.io\" /o:" + sonarqubeOrganisationKey + " /d:\"sonar.login=" + sonarQubeLogin + "\" /d:sonar.cs.opencover.reportsPaths=\"" + coverageFilePath + "\"";

     if (sonarQubePreview) {
         Information("Sonar: Running Sonar on PR " + AppVeyor.Environment.PullRequest.Number);


Trigger CI build

Trigger CI build

--- build.cake
+++ build.cake
@@ -79,10 +79,8 @@
             	UpdateAssemblyInfo = true,
             	OutputType = GitVersionOutput.BuildServer
         	});
-		}
-
+		}
 		versionInfo = GitVersion(new GitVersionSettings{ OutputType = GitVersionOutput.Json });
-
 		Information("Version: " + versionInfo.SemVer);
     }
 );


Enable coverage reporting.

Enable coverage reporting.

--- build.cake
+++ build.cake
@@ -13,7 +13,7 @@
 if (string.IsNullOrWhiteSpace(configuration))
     configuration = "Release";

-const bool reportCoverage = false;
+const bool reportCoverage = true;

 //////////////////////////////////////////////////////////////////////
 // PREPARATION


Fix build

Fix build

--- build.cake
+++ build.cake
@@ -1,5 +1,6 @@
 #tool "nuget:https://api.nuget.org/v3/index.json?package=KuduSync.NET"
 #tool "nuget:https://api.nuget.org/v3/index.json?package=Wyam&prerelease"
+#tool "nuget:https://api.nuget.org/v3/index.json?package=gitreleasemanager"
 #addin "nuget:https://api.nuget.org/v3/index.json?package=Cake.Git"
 #addin "nuget:https://api.nuget.org/v3/index.json?package=Cake.Kudu"
 #addin "nuget:https://api.nuget.org/v3/index.json?package=Cake.Wyam&prerelease"


update sonar config

update sonar config

--- build.cake
+++ build.cake
@@ -181,7 +181,7 @@
             Key = "ritter",
 			Version = "1.0",
             Url = "https://sonarcloud.io",
-            Login = "307f342a33ff5a38c90e1dfd37dadac7bc12bd2b",
+            Login = "f871e160aeb7cdda62aa6ae57cd275f515992035",
 			ArgumentCustomization = args => args
 				.Append($"/o:aritters-github"),
         });
@@ -192,7 +192,7 @@
     .IsDependentOn("Build")
     .Does(() => {
         SonarEnd(new SonarEndSettings {
-           Login = "307f342a33ff5a38c90e1dfd37dadac7bc12bd2b"
+           Login = "f871e160aeb7cdda62aa6ae57cd275f515992035"
         });
     });


Fix build.cake

Fix build.cake

--- build.cake
+++ build.cake
@@ -1,19 +1,26 @@
-#tool "nuget:?package=xunit.runner.console&version=2.4.1"
-
 const string TARGET = "Target";
 const string DEFAULT = "Default";
+
 const string NETCOREAPP21 = "netcoreapp2.1";
+const string NETCOREAPP20 = "netcoreapp2.2";
+const string NETCOREAPP30 = "netcoreapp3.0";
+
 const string CONFIGURATION = "Configuration";
 const string RELEASE = "Release";
 const string BUILD_NUMBER = "BuildNumber";
 const string FRAMEWORK = "Framework";
+const string PRE_RELEASE_SUFFIX = "PreReleaseSuffix";
+const string BETA = "beta";
+const string ALPHA = "alpha";
+const string RC="rc";
+

 //////////////////////////////////////////////////////////////////////
 // ARGUMENTS
 //////////////////////////////////////////////////////////////////////

 var target = Argument(TARGET, DEFAULT);
-var framework = Argument(FRAMEWORK, NETCOREAPP21);
+var framework = Argument(FRAMEWORK, NETCOREAPP30);

 //////////////////////////////////////////////////////////////////////
 // PREPARATION
@@ -33,20 +40,35 @@
                 ? int.Parse(EnvironmentVariable(BUILD_NUMBER))
                 : 0;

+var preReleaseSuffix = HasArgument(PRE_RELEASE_SUFFIX)
+        ? Argument<string>(PRE_RELEASE_SUFFIX)
+        : (AppVeyor.IsRunningOnAppVeyor && AppVeyor.Environment.Repository.Tag.IsTag)
+            ? null
+            : EnvironmentVariable(PRE_RELEASE_SUFFIX) != null
+                ? EnvironmentVariable(PRE_RELEASE_SUFFIX)
+                : BETA;

-var artifactsDirectory = Directory("./Artifacts");
+var versionSuffix = string.IsNullOrEmpty(preReleaseSuffix)
+                        ? null
+                        : preReleaseSuffix + "-" + buildNumber.ToString("D4");
+
+var artefactsDirectory = Directory("./Artifacts");

 //////////////////////////////////////////////////////////////////////
 // TASKS
 //////////////////////////////////////////////////////////////////////

 Task("Clean")
+    .Description("Cleans the artefacts, bin and obj directories.")
     .Does(() =>
     {
-        CleanDirectory(artifactsDirectory);
+        CleanDirectory(artefactsDirectory);
+        DeleteDirectories(GetDirectories("**/bin"), new DeleteDirectorySettings() { Force = true, Recursive = true });
+        DeleteDirectories(GetDirectories("**/obj"), new DeleteDirectorySettings() { Force = true, Recursive = true });
     });

 Task("Restore")
+    .Description("Restores NuGet packages.")
     .IsDependentOn("Clean")
     .Does(() =>
     {
@@ -54,57 +76,59 @@
     });

  Task("Build")
+    .Description("Builds the solution.")
     .IsDependentOn("Restore")
     .Does(() =>
     {
-        var projects = GetFiles("./src/**/*.csproj");
-        foreach(var project in projects)
-        {
-            DotNetCoreBuild(project.GetDirectory().FullPath,
-                new DotNetCoreBuildSettings()
-                {
-                    Configuration = configuration
-                });
-        }
+        DotNetCoreBuild(".",
+            new DotNetCoreBuildSettings()
+            {
+                Configuration = configuration,
+                NoRestore = true,
+                VersionSuffix = versionSuffix,
+            });
     });

 Task("Test")
+    .Description("Runs unit tests and outputs test results to the artefacts directory.")
     .IsDependentOn("Build")
-    .Does(() =>
+    .DoesForEach(GetFiles("./tests/**/*.csproj"), project =>
     {
-        var projects = GetFiles("./tests/**/*.csproj");
-        foreach(var project in projects)
-        {
-            DotNetCoreTest(project.GetDirectory().FullPath,
-                new DotNetCoreTestSettings()
-                {
-                    Configuration = configuration,
-                    NoBuild = true
-                });
-        }
+        Information(project);
+
+        DotNetCoreTest(project.ToString(),
+            new DotNetCoreTestSettings()
+            {
+                Configuration = configuration,
+                Logger = $"trx;LogFileName={project.GetFilenameWithoutExtension()}.trx",
+                NoBuild = true,
+                NoRestore = true,
+                ResultsDirectory = artefactsDirectory,
+                ArgumentCustomization = x => x.Append($"--logger html;LogFileName={project.GetFilenameWithoutExtension()}.html"),
+            });
     });

-Task("Package")
+Task("Pack")
+    .Description("Creates NuGet packages and outputs them to the artefacts directory.")
     .IsDependentOn("Test")
     .Does(() =>
     {
-        var revision = buildNumber.ToString();
-        foreach (var project in GetFiles("./src/**/*.csproj"))
-        {
-            Console.WriteLine(project);
-            DotNetCorePack(
-                project.GetDirectory().FullPath,
-                new DotNetCorePackSettings()
-                {
-                    Configuration = configuration,
-                    OutputDirectory = artifactsDirectory,
-                    VersionSuffix = revision
-                });
-        }
-    })
-    .ReportError(exception =>
-    {
-        Console.WriteLine($"Error: {exception.Message}");
+        var msBuildSettings = new DotNetCoreMSBuildSettings()
+                   // .SetTargetFramework(framework)
+                    .WithProperty("SymbolPackageFormat", "snupkg");
+
+        var dotNetCorePackSettings = new DotNetCorePackSettings()
+            {
+                Configuration = configuration,
+                IncludeSymbols = true,
+                MSBuildSettings = msBuildSettings,
+                NoBuild = true,
+                NoRestore = true,
+                OutputDirectory = artefactsDirectory,
+                VersionSuffix = versionSuffix,
+            };
+
+        DotNetCorePack(".", dotNetCorePackSettings);
     });

 //////////////////////////////////////////////////////////////////////
@@ -112,7 +136,10 @@
 //////////////////////////////////////////////////////////////////////

 Task("Default")
-    .IsDependentOn("Package");
+    .Description("Cleans, restores NuGet packages, builds the solution, runs unit tests and then creates NuGet packages.")
+    .IsDependentOn("Build")
+    .IsDependentOn("Test")
+    .IsDependentOn("Pack");

 //////////////////////////////////////////////////////////////////////
 // EXECUTION


OpenCover...

OpenCover...

--- build.cake
+++ build.cake
@@ -83,7 +83,7 @@
 {
     var openCoverSettings = new OpenCoverSettings
     {
-        Register = "user",
+        //Register = "user",
         SkipAutoProps = true,
         ArgumentCustomization = args => args.Append("-coverbytest:*.Tests.dll").Append("-mergebyhash")
     };


Build the projects before testing

Build the projects before testing

--- build.cake
+++ build.cake
@@ -10,7 +10,6 @@
 var framework = Argument("framework", "netcoreapp2.1");
 var configuration = Argument("configuration", "Release");

-var osuDesktop = new FilePath("./osu.Desktop/osu.Desktop.csproj");
 var osuSolution = new FilePath("./osu.sln");

 ///////////////////////////////////////////////////////////////////////////////
@@ -19,13 +18,14 @@

 Task("Compile")
 .Does(() => {
-    DotNetCoreBuild(osuDesktop.FullPath, new DotNetCoreBuildSettings {
+    DotNetCoreBuild(osuSolution.FullPath, new DotNetCoreBuildSettings {
         Framework = framework,
         Configuration = configuration
     });
 });

 Task("Test")
+.IsDependentOn("Compile")
 .Does(() => {
     var testAssemblies = GetFiles("**/*.Tests/bin/**/*.Tests.dll");


Enable all Net-Core unit tests

Enable all Net-Core unit tests

--- build.cake
+++ build.cake
@@ -11,7 +11,7 @@
 // TOOLS
 ///////////////////////////////////////////////////////////////////////////////

-#tool "nuget:?package=xunit.runner.console&version=2.1.0"
+#tool "nuget:?package=xunit.runner.console&version=2.2.0"
 #tool "nuget:?package=OpenCover"

 ///////////////////////////////////////////////////////////////////////////////
@@ -97,7 +97,6 @@
     CleanDirectory(parameters.BinRoot);
     CleanDirectory(parameters.TestsRoot);
 });
-

 Task("Restore-NuGet-Packages")
     .IsDependentOn("Clean")
@@ -175,19 +174,18 @@
     }
 }

-
 Task("Run-Net-Core-Unit-Tests")
     .IsDependentOn("Clean")
     .Does(() => {
         RunCoreTest("./tests/Avalonia.Base.UnitTests", parameters, false);
-        RunCoreTest("./tests/Avalonia.Controls.UnitTests", parameters, true);
-        RunCoreTest("./tests/Avalonia.Input.UnitTests", parameters, true);
-        RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", parameters, true);
-        RunCoreTest("./tests/Avalonia.Layout.UnitTests", parameters, true);
-        //RunCoreTest("./tests/Avalonia.Markup.UnitTests", parameters, true);
-        //RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", parameters, true);
-        RunCoreTest("./tests/Avalonia.Styling.UnitTests", parameters, true);
-        RunCoreTest("./tests/Avalonia.Visuals.UnitTests", parameters, true);
+        RunCoreTest("./tests/Avalonia.Controls.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Input.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Layout.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Markup.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Styling.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Visuals.UnitTests", parameters, false);
     });

 Task("Run-Unit-Tests")


Refactor build script

Refactor build script

--- build.cake
+++ build.cake
@@ -12,7 +12,6 @@

 var PROJECTS = DeserializeYamlFromFile<List<Project>> ("./projects.yaml");

-
 Func<FilePath> GetCakeToolPath = () =>
 {
 	var possibleExe = GetFiles ("../**/tools/Cake/Cake.exe").FirstOrDefault ();
@@ -23,6 +22,27 @@
 	var p = System.Diagnostics.Process.GetCurrentProcess ();
 	return new FilePath (p.Modules[0].FileName);
 };
+
+public class Project
+{
+	public Project ()
+	{
+		Name = string.Empty;
+		BuildScript = string.Empty;
+		TriggerPaths = new List<string> ();
+		BuildTargets = new List<string> ();
+	}
+
+	public string Name { get; set; }
+	public string BuildScript { get; set; }
+	public List<string> TriggerPaths { get; set; }
+	public List<string> BuildTargets { get; set; }
+
+	public override string ToString ()
+	{
+		return Name;
+	}
+}

 Task ("Default").Does (() =>
 {
@@ -88,25 +108,4 @@
 	}
 });

-public class Project
-{
-	public Project ()
-	{
-		Name = string.Empty;
-		BuildScript = string.Empty;
-		TriggerPaths = new List<string> ();
-		BuildTargets = new List<string> ();
-	}
-
-	public string Name { get; set; }
-	public string BuildScript { get; set; }
-	public List<string> TriggerPaths { get; set; }
-	public List<string> BuildTargets { get; set; }
-
-	public override string ToString ()
-	{
-		return Name;
-	}
-}
-
 RunTarget (TARGET);


Fix image creation logic

Fix image creation logic

--- build.cake
+++ build.cake
@@ -286,8 +286,11 @@
 			var sourceDir = BIN_DIR + Directory(runtime);
 			CreateDirectory(targetDir);
 			foreach (FilePath file in FrameworkFiles)
-				if (FileExists(sourceDir + file))
-					CopyFileToDirectory(sourceDir + file, targetDir);
+			{
+				var sourcePath = sourceDir + "/" + file;
+				if (FileExists(sourcePath))
+					CopyFileToDirectory(sourcePath, targetDir);
+			}
 		}
 	});


Updating cake build script to explicitly reference the public nuget server


add nuget to cake as a tool

add nuget to cake as a tool

--- build.cake
+++ build.cake
@@ -1,6 +1,5 @@
 #tool "dotnet:?package=GitVersion.Tool&version=5.8.1"
 #tool "dotnet:?package=coveralls.net&version=3.0.0"
-#addin nuget:?package=NuGet.CommandLine.XPlat&version=6.0.0
 #tool nuget:?package=NuGet.CommandLine.XPlat&version=6.0.0
 #addin nuget:?package=Cake.Json&version=4.0.0
 #addin nuget:?package=Newtonsoft.Json


Using specific version with cake as they keep breaking us

--- build.cake
+++ build.cake
@@ -1,8 +1,8 @@
 #tool nuget:https://nuget.org/api/v2/?package=XamarinComponent

-#addin nuget:https://nuget.org/api/v2/?package=Cake.XCode?version=2.0.13
-#addin nuget:https://nuget.org/api/v2/?package=Cake.FileHelpers?version=1.0.4
-#addin nuget:https://nuget.org/api/v2/?package=Cake.Xamarin?version=1.3.0.15
+#addin nuget:https://nuget.org/api/v2/?package=Cake.XCode&version=2.0.13
+#addin nuget:https://nuget.org/api/v2/?package=Cake.FileHelpers&version=1.0.4
+#addin nuget:https://nuget.org/api/v2/?package=Cake.Xamarin&version=1.3.0.15

 using System.Net;
 using System.Text.RegularExpressions;


Fixed PaymentController (Has to add it to the tranaction before checking the IsValid for it. (Updated by TFS to TFS Connector, server: http://1x:8080/, id 6523. )

git-tfs-id: [https://tfs.caes.ucdavis.edu:8088/tfs/DefaultCollection]$/CRP/Trunk/CRP;C1112

--- CRP/Controllers/PaymentController.cs
+++ CRP/Controllers/PaymentController.cs
@@ -60,13 +60,14 @@
                     if (!string.IsNullOrEmpty(check.Name) || check.Amount != 0 || !string.IsNullOrEmpty(check.Notes))
                     {
                         paymentLog = Copiers.CopyCheckValues(check, new PaymentLog());
-                        paymentLog.Check = true;
+                        paymentLog.Check = true;
+                        transaction.AddPaymentLog(paymentLog);
                         if (!paymentLog.IsValid())
                         {
+                            //var test = paymentLog.ValidationResults();
                             paymentLog.DisplayCheckInvalidMessage = true;
                             checkErrorFound = true;
                         }
-                        transaction.AddPaymentLog(paymentLog);
                     }
                 }
                 // update an existing one
@@ -78,6 +79,7 @@
                     {
                         if (!paymentLog.IsValid())
                         {
+                            var test = paymentLog.ValidationResults();
                             paymentLog.DisplayCheckInvalidMessage = true;
                             checkErrorFound = true;
                         }


update comments

update comments

--- CmcLibNet.Services/UI/IFilePicker.cs
+++ CmcLibNet.Services/UI/IFilePicker.cs
@@ -33,8 +33,9 @@
         string DefaultExt { get; set; }

         /// <summary>
-        /// Returns an OpenFileDialog instance
+        /// Returns an OpenFileDialog instance.
         /// </summary>
+        /// <returns>Dialog window.</returns>
         string ShowDialog();
     }
 }


Update Program.cs

Update Program.cs

Reference to System.IO required for class Directory.

--- app/Program.cs
+++ app/Program.cs
@@ -1,9 +1,9 @@
 // using System;
 // using System.Collections.Generic;
-// using System.IO;
 // using System.Linq;
 // using System.Threading.Tasks;

+using System.IO;                            // Directory.
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.Extensions.Configuration;


Started on a BBD style delay.

Started on a BBD style delay.

--- SharpSynth/Delay.cs
+++ SharpSynth/Delay.cs
@@ -3,6 +3,67 @@

 namespace SharpSynth
 {
+	public class BbdDelay : SynthComponent
+	{
+		private const float minimumDelay = 0.2f;
+		private const float maximumDelay = 1f;
+		private float lastBufferedSample;
+		private float head;
+		private float[] bbdBuffer;
+
+		public ISynthComponent DelayTime { get; set; } = FixedValue.One;
+
+		public ISynthComponent Mix { get; set; } = FixedValue.Half;
+
+		public ISynthComponent Feedback { get; set; } = FixedValue.Half;
+
+		public ISynthComponent Input { get; set; }
+
+		public BbdDelay()
+		{
+			// This gives 1 second of day with the slowest clock.
+
+			bbdBuffer = new float[SampleRate];
+		}
+
+		protected override void GenerateSamples(float[] buffer, int count, long timeBase)
+		{
+			if (Input == null)
+			{
+				for (var i = 0; i < buffer.Length; i++)
+					buffer[i] = 0;
+				return;
+			}
+
+			var delay = DelayTime.GenerateSamples(count, timeBase);
+			var mix = Mix.GenerateSamples(count, timeBase);
+			var feedback = Feedback.GenerateSamples(count, timeBase);
+			var input = Input.GenerateSamples(count, timeBase);
+
+			for (var i = 0; i < count; i++)
+			{
+				var d = Math.Min(maximumDelay, Math.Max(minimumDelay, delay[i]));
+				var m = Math.Min(1, Math.Max(0, mix[i]));
+				var f = Math.Min(1, Math.Max(0, feedback[i]));
+
+				var s = ReplaceDelayedSample(input[i], d, f);
+			}
+		}
+
+		private float ReplaceDelayedSample(float input, float delay, float feedback)
+		{
+			// This works because the BBD is 1 second long, in samples.
+
+			var ticksPerSample = 1 / delay;
+
+			// First read the output of the BBD.
+
+			//bbdBuffer[head]
+
+			return 0;
+		}
+	}
+
 	public class Delay : SynthComponent
 	{
 		private int head;


Method to class refactoring

Method to class refactoring

--- SignalR/Signaler.cs
+++ SignalR/Signaler.cs
@@ -6,120 +6,177 @@
 using System.Threading.Tasks;
 using SignalR.Infrastructure;

-namespace SignalR {
-    public class Signaler {
-        private static readonly ConcurrentDictionary<string, Timer> _timers = new ConcurrentDictionary<string, Timer>();
-        private static readonly Signaler _instance = new Signaler();
+namespace SignalR
+{
+	public class Signaler
+	{
+		private static readonly ConcurrentDictionary<string, Timer> _timers = new ConcurrentDictionary<string, Timer>();
+		private static readonly Signaler _instance = new Signaler();

-        public Signaler() {
-            DefaultTimeout = TimeSpan.FromMinutes(2);
-        }
+		public Signaler()
+		{
+			DefaultTimeout = TimeSpan.FromMinutes(2);
+		}

-        public static Signaler Instance {
-            get {
-                return _instance;
-            }
-        }
+		public static Signaler Instance
+		{
+			get
+			{
+				return _instance;
+			}
+		}

-        public virtual ISignalBus SignalBus {
-            get {
-                return DependencyResolver.Resolve<ISignalBus>();
-            }
-        }
+		public virtual ISignalBus SignalBus
+		{
+			get
+			{
+				return DependencyResolver.Resolve<ISignalBus>();
+			}
+		}

-        public virtual TimeSpan DefaultTimeout { get; set; }
+		public virtual TimeSpan DefaultTimeout { get; set; }

-        public virtual Task Signal(string eventKey) {
-            return SignalBus.Signal(eventKey);
-        }
+		public virtual Task Signal(string eventKey)
+		{
+			return SignalBus.Signal(eventKey);
+		}

-        public virtual Task<SignalResult> Subscribe(string eventKey) {
-            return Subscribe(DefaultTimeout, eventKey);
-        }
+		public virtual Task<SignalResult> Subscribe(string eventKey)
+		{
+			return Subscribe(DefaultTimeout, eventKey);
+		}

-        public virtual Task<SignalResult> Subscribe(IEnumerable<string> eventKeys) {
-            return Subscribe(eventKeys.ToArray());
-        }
+		public virtual Task<SignalResult> Subscribe(IEnumerable<string> eventKeys)
+		{
+			return Subscribe(eventKeys.ToArray());
+		}

-        public virtual Task<SignalResult> Subscribe(TimeSpan timeout, string eventKey) {
-            return Subscribe(timeout, new[] { eventKey });
-        }
+		public virtual Task<SignalResult> Subscribe(TimeSpan timeout, string eventKey)
+		{
+			return Subscribe(timeout, new[] { eventKey });
+		}

-        public virtual Task<SignalResult> Subscribe(params string[] eventKeys) {
-            return Subscribe(DefaultTimeout, eventKeys);
-        }
+		public virtual Task<SignalResult> Subscribe(params string[] eventKeys)
+		{
+			return Subscribe(DefaultTimeout, eventKeys);
+		}

-        public virtual Task<SignalResult> Subscribe(TimeSpan timeout, IEnumerable<string> eventKeys) {
-            return Subscribe(timeout, CancellationToken.None, eventKeys);
-        }
+		public virtual Task<SignalResult> Subscribe(TimeSpan timeout, IEnumerable<string> eventKeys)
+		{
+			return Subscribe(timeout, CancellationToken.None, eventKeys);
+		}

-        public virtual Task<SignalResult> Subscribe(TimeSpan timeout, CancellationToken cancellationToken, IEnumerable<string> eventKeys) {
-            return Subscribe(timeout, cancellationToken, eventKeys.ToArray());
-        }
+		public virtual Task<SignalResult> Subscribe(TimeSpan timeout, CancellationToken cancellationToken, IEnumerable<string> eventKeys)
+		{
+			return Subscribe(timeout, cancellationToken, eventKeys.ToArray());
+		}

-        public virtual Task<SignalResult> Subscribe(TimeSpan timeout, CancellationToken cancellationToken, params string[] eventKeys) {
-            var tcs = new TaskCompletionSource<SignalResult>();
+		public virtual Task<SignalResult> Subscribe(TimeSpan timeout, CancellationToken cancellationToken, params string[] eventKeys)
+		{
+			var tcs = new TaskCompletionSource<SignalResult>();
+			var timerKey = Guid.NewGuid().ToString();

-            var handlerCalled = false;
-            var handlerLock = new object();
+			var signalAction = new SafeHandleEventAndSetResultAction(SignalBus,tcs, timerKey, eventKeys);

-            EventHandler<SignaledEventArgs> onSignaled = null;
-            var timerKey = Guid.NewGuid().ToString();
+
+			foreach (var eventKey in eventKeys)
+			{
+				SignalBus.AddHandler(eventKey, signalAction.Handler);
+			}

-            onSignaled = (source, e) => {
-                SafeHandleEventAndSetResult(handlerLock, onSignaled, ref handlerCalled, tcs, timerKey, e.EventKey, eventKeys, canceled: false, timedOut: false);
-            };
+			if (cancellationToken != CancellationToken.None)
+			{
+				cancellationToken.Register(signalAction.SetCanceled);
+			}

-            foreach (var eventKey in eventKeys) {
-                SignalBus.AddHandler(eventKey, onSignaled);
-            }
+			var timer = new Timer(signalAction.SetTimedOut,
+						null,
+						timeout,
+						timeout);

-            if (cancellationToken != CancellationToken.None) {
-                cancellationToken.Register(() => SafeHandleEventAndSetResult(handlerLock, onSignaled, ref handlerCalled, tcs, timerKey, signaledEventKey: null, eventKeys: eventKeys, canceled: true, timedOut: false));
-            }
+			_timers.TryAdd(timerKey, timer);

-            var timer = new Timer(
-                        _ => SafeHandleEventAndSetResult(handlerLock, onSignaled, ref handlerCalled, tcs, timerKey, signaledEventKey: null, eventKeys: eventKeys, canceled: false, timedOut: true),
-                        null,
-                        timeout,
-                        timeout);
+			return tcs.Task;
+		}

-            _timers.TryAdd(timerKey, timer);
+		private class SafeHandleEventAndSetResultAction
+		{
+			public SafeHandleEventAndSetResultAction(ISignalBus signalBus,TaskCompletionSource<SignalResult> tcs, string timerKey, IEnumerable<string> eventKeys)
+			{
+				locker = new object();
+				Handler = (sender, args) =>
+				{
+					signaledEventKey = args.EventKey;
+					SafeHandleEventAndSetResult();
+				};
+				Tcs = tcs;
+				this.signalBus = signalBus;
+				this.timerKey = timerKey;
+				this.eventKeys = eventKeys;
+			}

-            return tcs.Task;
-        }
+			private readonly object locker;

-        private void SafeHandleEventAndSetResult(
-            object locker,
-            EventHandler<SignaledEventArgs> handler,
-            ref bool handlerCalled,
-            TaskCompletionSource<SignalResult> tcs,
-            string timerKey,
-            string signaledEventKey,
-            IEnumerable<string> eventKeys,
-            bool canceled,
-            bool timedOut) {
-            lock (locker) {
-                if (!handlerCalled) {
-                    handlerCalled = true;
+			public EventHandler<SignaledEventArgs> Handler { get; private set; }

-                    foreach (var eventKey in eventKeys) {
-                        SignalBus.RemoveHandler(eventKey, handler);
-                    }
+			private TaskCompletionSource<SignalResult> Tcs { get; set; }

-                    if (canceled) {
-                        tcs.SetCanceled();
-                    }
-                    else {
-                        tcs.SetResult(new SignalResult { TimedOut = timedOut, EventKey = signaledEventKey });
-                    }
+			private readonly ISignalBus signalBus;
+			private readonly string timerKey;

-                    Timer timer;
-                    if (_timers.TryRemove(timerKey, out timer)) {
-                        timer.Dispose();
-                    }
-                }
-            }
-        }
-    }
+			private string signaledEventKey;
+
+			private readonly IEnumerable<string> eventKeys;
+
+			private bool canceled;
+
+			private bool timedOut;
+
+			private bool handlerCalled;
+
+			private void SafeHandleEventAndSetResult()
+			{
+				lock (locker)
+				{
+					if (!handlerCalled)
+						return;
+
+					handlerCalled = true;
+
+					foreach (var eventKey in eventKeys)
+					{
+						signalBus.RemoveHandler(eventKey, Handler);
+					}
+
+					if (canceled)
+					{
+						Tcs.SetCanceled();
+					}
+					else
+					{
+						Tcs.SetResult(new SignalResult { TimedOut = timedOut, EventKey = signaledEventKey });
+					}
+
+					Timer timer;
+					if (_timers.TryRemove(timerKey, out timer))
+					{
+						timer.Dispose();
+					}
+				}
+			}
+
+			public void SetCanceled()
+			{
+				canceled = true;
+				SafeHandleEventAndSetResult();
+			}
+
+			public void SetTimedOut(object state)
+			{
+				timedOut = true;
+				SafeHandleEventAndSetResult();
+			}
+		}
+
+	}
 }


[Modify] Edit it

[Modify] Edit it

--- websocket-sharp/Net/ClientSslConfiguration.cs
+++ websocket-sharp/Net/ClientSslConfiguration.cs
@@ -74,6 +74,9 @@
     /// <param name="targetHost">
     /// A <see cref="string"/> that represents the target host server name.
     /// </param>
+    /// <exception cref="ArgumentNullException">
+    /// <paramref name="targetHost"/> is <see langword="null"/>.
+    /// </exception>
     public ClientSslConfiguration (string targetHost)
     {
       if (targetHost == null)


try to fix GC not running durin test

try to fix GC not running durin test

--- compiler/NUnit.Tests/Frontend/LexerTest.cs
+++ compiler/NUnit.Tests/Frontend/LexerTest.cs
@@ -139,19 +139,21 @@
         [Test]
         public void DestructorTest()
         {
-            // pFilename -- arbitrary
+
+                // pFilename -- arbitrary
             string filename = TestContext.CurrentContext.TestDirectory + @"/Frontend/testdata/LexerTest1.txt";
-
-            // create a lexer
-            Lex = new Lexer(filename);
-
-            // release the lexer, so that the file will close
-            Lex = null;
-            Assert.Null(Lex);
-
-            // invoke garbage collector to ensure destructor runs now
-            GC.Collect();
-            GC.WaitForPendingFinalizers();
+            {
+                // create a lexer
+                Lex = new Lexer(filename);
+
+                // release the lexer, so that the file will close
+                Lex = null;
+                Assert.Null(Lex);
+
+                // invoke garbage collector to ensure destructor runs now
+                GC.Collect();
+                GC.WaitForPendingFinalizers();
+            }

             // check if the file is infact, closed
             var fileInfo = new FileInfo(filename);


Fixed joystick up and left buttons on Linux.
Issue: 1

git-svn-id: 710bf7efd0cb1e604ce28c2b3b9a8b7b2cd2e39e@91 de0ceee1-c12a-0410-b4aa-b6e97b09e4b8

--- runner/Program.cs
+++ runner/Program.cs
@@ -62,10 +62,13 @@
 				if (SdlDotNet.Input.Keyboard.IsKeyPressed(SdlDotNet.Input.Key.Space)) buttons |= UserInput.Buttons.Action;
 				if (SdlDotNet.Input.Keyboard.IsKeyPressed(SdlDotNet.Input.Key.Escape)) buttons |= UserInput.Buttons.Back;
 				if (joy != null) {
-					if (joy.GetAxisPosition(SdlDotNet.Input.JoystickAxis.Vertical) == 0) buttons |= UserInput.Buttons.Up;
-					if (joy.GetAxisPosition(SdlDotNet.Input.JoystickAxis.Vertical) == 1) buttons |= UserInput.Buttons.Down;
-					if (joy.GetAxisPosition(SdlDotNet.Input.JoystickAxis.Horizontal) == 0) buttons |= UserInput.Buttons.Left;
-					if (joy.GetAxisPosition(SdlDotNet.Input.JoystickAxis.Horizontal) == 1) buttons |= UserInput.Buttons.Right;
+					//On Windows, the return values are 0, 1, or ~0.5
+					//On Linux, the return values are ~0, 1, or ~0.5
+					//Thus, the equality operator cannot be used - in my opinion these are safe approximations.
+					if (joy.GetAxisPosition(SdlDotNet.Input.JoystickAxis.Vertical) < 0.2 ) buttons |= UserInput.Buttons.Up;
+					if (joy.GetAxisPosition(SdlDotNet.Input.JoystickAxis.Vertical) > 0.8) buttons |= UserInput.Buttons.Down;
+					if (joy.GetAxisPosition(SdlDotNet.Input.JoystickAxis.Horizontal) < 0.2) buttons |= UserInput.Buttons.Left;
+					if (joy.GetAxisPosition(SdlDotNet.Input.JoystickAxis.Horizontal) > 0.8) buttons |= UserInput.Buttons.Right;
 					if (joy.GetButtonState(0) == SdlDotNet.Input.ButtonKeyState.Pressed) buttons |= UserInput.Buttons.Action;
 					if (joy.GetButtonState(1) == SdlDotNet.Input.ButtonKeyState.Pressed) buttons |= UserInput.Buttons.Back;
 				}


Remove empty file.

Remove empty file.


Change wording of error message when a typo'd enum is used as a switch statement case to be a little more helpful.

--- csharp/Crayon/ParseTree/SwitchStatement.cs
+++ csharp/Crayon/ParseTree/SwitchStatement.cs
@@ -123,7 +123,19 @@

 						if (chunk.Cases[i] is IntegerConstant) integers++;
 						else if (chunk.Cases[i] is StringConstant) strings++;
-						else throw new ParserException(chunk.Cases[i].FirstToken, "Only strings and integers can be used in a switch statement.");
+						else
+						{
+							if (chunk.Cases[i] is DotStep)
+							{
+								string field = ((DotStep)chunk.Cases[i]).StepToken.Value;
+								if (field.ToUpperInvariant() == field)
+								{
+									throw new ParserException(chunk.Cases[i].FirstToken,
+										"Only strings, integers, and enums can be used in a switch statement. It looks like this is probably supposed to be an enum. Make sure that it is spelled correctly.");
+								}
+							}
+							throw new ParserException(chunk.Cases[i].FirstToken, "Only strings, integers, and enums can be used in a switch statement.");
+						}
 					}
 				}


Flexible cast of identity_scope.

Flexible cast of identity_scope.

--- src/RabbitDB/Storage/SqlDbProvider.cs
+++ src/RabbitDB/Storage/SqlDbProvider.cs
@@ -12,7 +12,7 @@

         public override string ScopeIdentity
         {
-            get { return "; Select SCOPE_IDENTITY() as id"; }
+            get { return "; Select CAST(SCOPE_IDENTITY() AS {0}) as id"; }
         }

         internal SqlDbProvider(string connectionString)


Add back partial modifier on Extensions.

--- src/Renci.SshNet/Common/Extensions.cs
+++ src/Renci.SshNet/Common/Extensions.cs
@@ -15,7 +15,7 @@
     /// <summary>
     /// Collection of different extension method
     /// </summary>
-    internal static class Extensions
+    internal static partial class Extensions
     {
         /// <summary>
         /// Determines whether [is null or white space] [the specified value].


refactor: better naming

refactor: better naming

--- src/ReniUI/Test/AutoCompleteSimple.cs
+++ src/ReniUI/Test/AutoCompleteSimple.cs
@@ -25,14 +25,14 @@
         public void GetDeclarationOptions()
         {
             var compiler = CompilerBrowser.FromText(text);
-            for(var i = 0; i < text.Length; i++)
+            for(var index = 0; index < text.Length; index++)
             {
-                var offset = text.Length - i - 1;
+                var offset = text.Length - index - 1;
                 var position = compiler.Source + offset;
                 if(offset > 0 && (position + -1).Span(2).Id != "\r\n")
                 {
                     var t = compiler.DeclarationOptions(offset);
-                    Tracer.Assert(t != null, () => (new Source(text) + i).Dump());
+                    Tracer.Assert(t != null, () => (new Source(text) + index).Dump());
                 }
             }
         }


make queries fuzzier

make queries fuzzier

--- src/ResinCore/Querying/QueryParser.cs
+++ src/ResinCore/Querying/QueryParser.cs
@@ -11,7 +11,7 @@
         private readonly IAnalyzer _analyzer;
         private readonly float _fuzzySimilarity;

-        public QueryParser(IAnalyzer analyzer, float fuzzySimilarity = 0.85f)
+        public QueryParser(IAnalyzer analyzer, float fuzzySimilarity = 0.75f)
         {
             _analyzer = analyzer;
             _fuzzySimilarity = fuzzySimilarity;


Cleans up NamedType.

Cleans up NamedType.

--- src/Rook.Compiling/Types/NamedType.cs
+++ src/Rook.Compiling/Types/NamedType.cs
@@ -50,7 +50,7 @@
         }

         private readonly string name;
-        private readonly IEnumerable<DataType> innerTypes;
+        private readonly DataType[] innerTypes;
         private readonly Lazy<string> fullName;

         public NamedType(string name, params DataType[] innerTypes)
@@ -67,16 +67,11 @@

             var genericArguments = type.GetGenericArguments();

-            this.name = type.Namespace + "." + type.Name.Replace("`" + genericArguments.Length, "");
+            name = type.Namespace + "." + type.Name.Replace("`" + genericArguments.Length, "");

-            if (type.IsGenericTypeDefinition)
-            {
-                this.innerTypes = genericArguments.Select(x => TypeVariable.CreateGeneric()).ToArray();
-            }
-            else
-            {
-                this.innerTypes = genericArguments.Select(x => new NamedType(x)).ToArray();
-            }
+            innerTypes = type.IsGenericTypeDefinition
+                ? genericArguments.Select(x => (DataType)TypeVariable.CreateGeneric()).ToArray()
+                : genericArguments.Select(x => (DataType)new NamedType(x)).ToArray();

             fullName = new Lazy<string>(GetFullName);
         }
@@ -119,17 +114,20 @@
         private string GetFullName()
         {
             if (innerTypes.Any())
-                return System.String.Format("{0}<{1}>", CleanedName(name), System.String.Join(", ", innerTypes));
+                return System.String.Format("{0}<{1}>", CleanedName, System.String.Join(", ", (IEnumerable<DataType>)innerTypes));

-            return CleanedName(name);
+            return CleanedName;
         }

-        private static string CleanedName(string name)
+        private string CleanedName
         {
-            return name
-                .Replace("System.Boolean", "bool")
-                .Replace("System.Int32", "int")
-                .Replace("System.String", "string");
+            get
+            {
+                return name
+                    .Replace("System.Boolean", "bool")
+                    .Replace("System.Int32", "int")
+                    .Replace("System.String", "string");
+            }
         }
     }
 }


Fix build break from last commit 9c65207.  Mono 2.4 lacks string.join(string, List<string>), or some auto casting is missing

--- OpenSim/Tools/pCampBot/BotManager.cs
+++ OpenSim/Tools/pCampBot/BotManager.cs
@@ -594,7 +594,7 @@
                         currentSim != null ? currentSim.Name : "(none)",
                         bot.ConnectionState,
                         bot.SimulatorsCount,
-                        string.Join(",", bot.Behaviours.ConvertAll<string>(behaviour => behaviour.AbbreviatedName)));
+                        string.Join(",", bot.Behaviours.ConvertAll<string>(behaviour => behaviour.AbbreviatedName).ToArray()));
                 }
             }


Open current log file was improved

Open current log file was improved

--- src/SIM.Tool.Base/InstanceHelperEx.cs
+++ src/SIM.Tool.Base/InstanceHelperEx.cs
@@ -1,10 +1,14 @@
 namespace SIM.Tool.Base
 {
   using System;
+  using System.Collections.Generic;
+  using System.Diagnostics;
   using System.IO;
   using System.Linq;
   using System.Text.RegularExpressions;
+  using System.Threading;
   using System.Windows;
+  using System.Windows.Documents;
   using Microsoft.Web.Administration;
   using SIM.Instances;
   using Sitecore.Diagnostics.Base;
@@ -39,55 +43,70 @@
       Assert.ArgumentNotNull(instance, "instance");
       Assert.ArgumentNotNull(owner, "owner");

-      string dataFolderPath = instance.DataFolderPath;
+      var dataFolderPath = instance.DataFolderPath;
       FileSystem.FileSystem.Local.Directory.AssertExists(dataFolderPath, "The data folder ({0}) of the {1} instance doesn't exist".FormatWith(dataFolderPath, instance.Name));
-      var logs = instance.LogsFolderPath;
-      logFileType = logFileType ?? GetLogFileTypes(owner, logs);
-      if (logFileType == null)
-      {
-        return;
-      }
-
-      var pattern = logFileType + "*.txt";
-      var files = FileSystem.FileSystem.Local.Directory.GetFiles(logs, pattern) ?? new string[0];
+
+      var logsFolderPath = instance.LogsFolderPath;
+      var logFilePrefix = logFileType ?? GetLogFileTypes(owner, logsFolderPath);
+      if (logFilePrefix == null)
+      {
+        Action waitForLogs = delegate
+        {
+          while (logFilePrefix == null)
+          {
+            logFilePrefix = GetLogFileTypes(owner, logsFolderPath);
+            Thread.Sleep(100);
+          }
+        };
+
+        WindowHelper.LongRunningTask(waitForLogs, "Waiting for log files", owner, null, "Waiting for log files to be created in the \"{0}\" folder.".FormatWith(logsFolderPath));
+      }
+
+      var logFilePattern = logFilePrefix + "*.txt";
+      var files = FileSystem.FileSystem.Local.Directory.GetFiles(logsFolderPath, logFilePattern) ?? new string[0];
       var logFilePath = files.OrderByDescending(FileSystem.FileSystem.Local.File.GetCreationTimeUtc).FirstOrDefault();
       if (string.IsNullOrEmpty(logFilePath))
       {
+        Action waitForLogs = delegate
+        {
+          while (string.IsNullOrEmpty(logFilePath))
+          {
+            var files2 = FileSystem.FileSystem.Local.Directory.GetFiles(logsFolderPath, logFilePattern) ?? new string[0];
+            logFilePath = files2.OrderByDescending(FileSystem.FileSystem.Local.File.GetCreationTimeUtc).FirstOrDefault();
+            Thread.Sleep(100);
+          }
+        };
+
+        WindowHelper.LongRunningTask(waitForLogs, "Waiting for log files", owner, null, "Waiting for log files to be created in the \"{0}\" folder.".FormatWith(logsFolderPath));
+      }
+
+      var logViewer = GetLogViewer();
+      if (string.IsNullOrEmpty(logViewer))
+      {
         return;
       }

-      string logviewer = WinAppSettings.AppToolsLogViewer.Value;
-      if (string.IsNullOrEmpty(logviewer))
-      {
-        return;
-      }
-
-      if (logviewer == "logview.exe")
-      {
-        logviewer = ApplicationManager.GetEmbeddedFile("logview.zip", "SIM.Tool.Windows", "logview.exe");
-      }
-
-      var fileSystemWatcher = new FileSystemWatcher(logs)
-      {
-        Filter = pattern,
+      var fileSystemWatcher = new FileSystemWatcher(logsFolderPath)
+      {
+        Filter = logFilePattern,
         IncludeSubdirectories = false
       };

-      bool ignore = false;
-
-      var process = WindowHelper.RunApp(logviewer, logFilePath);
-      if (process == null)
+      var reopenLogViewer = false;
+
+      var currentProcess = WindowHelper.RunApp(logViewer, logFilePath);
+      if (currentProcess == null)
       {
         return;
       }
-
+
       // we need to stop all this magic when application closes
-      process.Exited += (sender, args) =>
+      currentProcess.Exited += delegate
       {
         // but shouldn't if it is initiated by this magic
-        if (ignore)
-        {
-          ignore = false;
+        if (reopenLogViewer)
+        {
+          reopenLogViewer = false;
           return;
         }

@@ -98,26 +117,62 @@
       {
         try
         {
+          if (args.ChangeType != WatcherChangeTypes.Created)
+          {
+            return;
+          }
+
+          var filePath = args.FullPath;
+          if (!filePath.Contains(logFilePrefix))
+          {
+            return;
+          }
+
           // indicate that magic begins
-          ignore = true;
+          reopenLogViewer = true;

           // magic begins
-          process.Kill();
-          files = FileSystem.FileSystem.Local.Directory.GetFiles(logs, pattern) ?? new string[0];
-          logFilePath = files.OrderByDescending(FileSystem.FileSystem.Local.File.GetCreationTimeUtc).First();
-          process = WindowHelper.RunApp(logviewer, logFilePath);
+          currentProcess.Kill();
+
+          currentProcess = WindowHelper.RunApp(logViewer, filePath);
+
+          // we need to stop all this magic when application closes
+          currentProcess.Exited += delegate
+          {
+            // but shouldn't if it is initiated by this magic
+            if (reopenLogViewer)
+            {
+              reopenLogViewer = false;
+              return;
+            }
+
+            fileSystemWatcher.EnableRaisingEvents = false;
+          };
         }
         catch (Exception ex)
         {
+          fileSystemWatcher.EnableRaisingEvents = false;
           Log.Error(ex, "Unhandled error happened while reopening log file");
         }
-        finally
-        {
-          fileSystemWatcher.EnableRaisingEvents = false;
-        }
       };

       fileSystemWatcher.EnableRaisingEvents = true;
+    }
+
+    private static string GetLogViewer()
+    {
+      var logviewer = WinAppSettings.AppToolsLogViewer.Value;
+      if (string.IsNullOrEmpty(logviewer))
+      {
+        return null;
+      }
+
+      if (logviewer != "logview.exe")
+      {
+        return logviewer;
+      }
+
+      return ApplicationManager.GetEmbeddedFile("logview.zip", "SIM.Tool.Windows", "logview.exe");
     }

     public static void OpenInBrowserAsAdmin([NotNull] Instance instance, [NotNull] Window owner, [CanBeNull] string pageUrl = null, [CanBeNull] string browser = null, [CanBeNull] string[] parameters = null)
@@ -241,8 +296,7 @@
       {
         return WindowHelper.AskForSelection("Open current log file", "Choose log file type", "There are several types of log files in Sitecore. Please choose what type do you need?", groups, owner, groups.First(), false, true);
       }
-
-      WindowHelper.ShowMessage("There are no log files", MessageBoxButton.OK, MessageBoxImage.Asterisk);
+
       return null;
     }


Improve engine code

Improve engine code

--- src/Strinken/Engine/StrinkenEngine.cs
+++ src/Strinken/Engine/StrinkenEngine.cs
@@ -98,13 +98,13 @@
                     {
                         state = this.PushAndMove(State.OnArgumentInitializerOrSeparator, tokenType, tokenSubtype);
                     }
-                    else if (tokenType != TokenType.Argument || (tokenType == TokenType.Argument && tokenSubtype != TokenSubtype.Base))
-                    {
-                        state = this.RaiseError(string.Format(Errors.IllegalCharacter, (char)this.cursor.Value, this.cursor.Position));
-                    }
-                    else
+                    else if (tokenType == TokenType.Argument && tokenSubtype == TokenSubtype.Base)
                     {
                         state = this.AppendAndMove(currentState);
+                    }
+                    else
+                    {
+                        state = this.RaiseIllegalCharacterError();
                     }

                     break;
@@ -114,13 +114,13 @@
                     break;

                 case SpecialCharacter.ArgumentSeparator:
-                    if (tokenType == TokenType.Tag || tokenType == TokenType.Filter)
-                    {
-                        state = this.RaiseError(string.Format(Errors.IllegalCharacter, (char)this.cursor.Value, this.cursor.Position));
-                    }
-                    else
-                    {
-                        state = this.PushAndMove(State.OnArgumentInitializerOrSeparator, tokenType, tokenSubtype);
+                    if (tokenType == TokenType.Argument)
+                    {
+                        state = this.PushAndMove(State.OnArgumentInitializerOrSeparator, TokenType.Argument, tokenSubtype);
+                    }
+                    else
+                    {
+                        state = this.RaiseIllegalCharacterError();
                     }

                     break;
@@ -130,7 +130,7 @@
                     break;

                 default:
-                    state = this.AppendAndMove(currentState, tokenType != TokenType.Argument || (tokenType == TokenType.Argument && tokenSubtype != TokenSubtype.Base));
+                    state = this.AppendAndMove(currentState, !(tokenType == TokenType.Argument && tokenSubtype == TokenSubtype.Base));
                     break;
             }

@@ -173,7 +173,7 @@
                     }
                     else
                     {
-                        state = this.RaiseError(string.Format(Errors.IllegalCharacter, (char)this.cursor.Value, this.cursor.Position));
+                        state = this.RaiseIllegalCharacterError();
                     }

                     break;
@@ -185,7 +185,7 @@
                     }
                     else
                     {
-                        state = this.RaiseError(string.Format(Errors.IllegalCharacter, (char)this.cursor.Value, this.cursor.Position));
+                        state = this.RaiseIllegalCharacterError();
                     }

                     break;
@@ -197,7 +197,7 @@
                     }
                     else
                     {
-                        state = this.RaiseError(string.Format(Errors.IllegalCharacter, (char)this.cursor.Value, this.cursor.Position));
+                        state = this.RaiseIllegalCharacterError();
                     }

                     break;
@@ -211,13 +211,13 @@
                     }
                     else
                     {
-                        state = this.RaiseError(string.Format(Errors.IllegalCharacter, (char)this.cursor.Value, this.cursor.Position));
-                    }
-
-                    break;
-
-                default:
-                    state = this.AppendAndMove(nextState, tokenType != TokenType.Argument || (tokenType == TokenType.Argument && tokenSubtype != TokenSubtype.Base));
+                        state = this.RaiseIllegalCharacterError();
+                    }
+
+                    break;
+
+                default:
+                    state = this.AppendAndMove(nextState, !(tokenType == TokenType.Argument && tokenSubtype == TokenSubtype.Base));
                     break;
             }

@@ -289,7 +289,7 @@
             var value = (char)this.cursor.Value;
             if (validate && value.IsInvalidTokenNameCharacter())
             {
-                return this.RaiseError(string.Format(Errors.IllegalCharacter, (char)this.cursor.Value, this.cursor.Position));
+                return this.RaiseIllegalCharacterError();
             }

             this.tokenStack.Append((char)this.cursor.Value);
@@ -342,5 +342,11 @@
                     throw new InvalidOperationException();
             }
         }
+
+        /// <summary>
+        /// Handle the <see cref="RaiseError"/> method for an illegal character.
+        /// </summary>
+        /// <returns><see cref="State.InvalidString"/></returns>
+        private State RaiseIllegalCharacterError() => this.RaiseError(string.Format(Errors.IllegalCharacter, (char)this.cursor.Value, this.cursor.Position));
     }
 }


Added input variable validation

Added input variable validation

--- src/Take.Blip.Builder/Models/Input.cs
+++ src/Take.Blip.Builder/Models/Input.cs
@@ -1,4 +1,5 @@
 using System.ComponentModel.DataAnnotations;
+using System.Text.RegularExpressions;
 using Lime.Messaging.Contents;

 namespace Take.Blip.Builder.Models
@@ -8,6 +9,8 @@
     /// </summary>
     public class Input : IValidable
     {
+        private static readonly Regex VariableValidationRegex = new Regex("^([a-zA-Z0-9\\.]+)$", RegexOptions.Compiled);
+
         /// <summary>
         /// Indicates that the state input should be skipped.
         /// </summary>
@@ -38,7 +41,13 @@
                 {
                     throw new ValidationException("The media type should be provided when using the 'type' validation rule");
                 }
-            }
+            }
+
+            if (!string.IsNullOrWhiteSpace(Variable)
+                && !VariableValidationRegex.IsMatch(Variable))
+            {
+                throw new ValidationException("The input variable name should be composed only by letters, numbers and dots");
+            }
         }
     }
 }


Add custom contract resolver

Add custom contract resolver

It is added back because request classes are not meant to be serialized outside of the library. That way we don't have to annotate request classes with json related attributes as much as we'd have to without global custom contract resolver.

--- src/Telegram.Bot/TelegramBotClient.cs
+++ src/Telegram.Bot/TelegramBotClient.cs
@@ -9,6 +9,7 @@
 using System.Threading;
 using System.Threading.Tasks;
 using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
 using Telegram.Bot.Args;
 using Telegram.Bot.Exceptions;
 using Telegram.Bot.Helpers;
@@ -41,7 +42,11 @@

         private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings
         {
-            NullValueHandling = NullValueHandling.Ignore
+            NullValueHandling = NullValueHandling.Ignore,
+            ContractResolver = new DefaultContractResolver
+            {
+                NamingStrategy = new SnakeCaseNamingStrategy()
+            }
         };

         #region Config Properties


Instruction copy now copies SequencePoint for better debug

--- src/Tools/EngineWeaver/CecilCopier.cs
+++ src/Tools/EngineWeaver/CecilCopier.cs
@@ -393,6 +393,9 @@
                 var methodInfo = typeof(Instruction).GetMethod("Create",new Type[]{def.OpCode.GetType(),def.Operand.GetType()});
                 ret = (Instruction) methodInfo.Invoke(null,new object[]{def.OpCode,def.Operand});
             }
+
+            ret.SequencePoint = def.SequencePoint;
+
             instructions.Add(ret);
             return ret;
         }


Refactored the AudioRecorder so inherited classes have more control.

--- Palaso.Media/Naudio/AudioRecorder.cs
+++ Palaso.Media/Naudio/AudioRecorder.cs
@@ -36,28 +36,28 @@

 	public class AudioRecorder : IAudioRecorder, IDisposable
 	{
-		private readonly int _maxMinutes;
+		protected readonly int _maxMinutes;

 		/// <summary>
 		/// This guy is always working, whether we're playing, recording, or just idle (monitoring)
 		/// </summary>
-		private WaveIn _waveIn;
+		protected WaveIn _waveIn;

 		/// <summary>
 		/// This guy is disposed each time the client calls stop to stop recording and gets recreated
 		/// each time the client starts recording (i.e. using BeginRecording).
 		/// </summary>
-		private WaveFileWriter _writer;
-
-		private UnsignedMixerControl _volumeControl;
-		private double _microphoneLevel = 100;
-		private RecordingState _recordingState = RecordingState.Stopped;
-		private WaveFormat _recordingFormat;
-		private RecordingProgressEventArgs _recProgressEventArgs = new RecordingProgressEventArgs();
-		private PeakLevelEventArgs _peakLevelEventArgs = new PeakLevelEventArgs();
-		private double _prevRecordedTime;
-
-		public SampleAggregator SampleAggregator { get; private set; }
+		protected WaveFileWriter _writer;
+
+		protected UnsignedMixerControl _volumeControl;
+		protected double _microphoneLevel = 100;
+		protected RecordingState _recordingState = RecordingState.Stopped;
+		protected WaveFormat _recordingFormat;
+		protected RecordingProgressEventArgs _recProgressEventArgs = new RecordingProgressEventArgs();
+		protected PeakLevelEventArgs _peakLevelEventArgs = new PeakLevelEventArgs();
+		protected double _prevRecordedTime;
+
+		public SampleAggregator SampleAggregator { get; protected set; }
 		public RecordingDevice SelectedDevice { get; set; }
 		public TimeSpan RecordedTime { get; set; }

@@ -85,14 +85,14 @@
 		}

 		/// ------------------------------------------------------------------------------------
-		public void Dispose()
+		public virtual void Dispose()
 		{
 			CloseWriter();
 			CloseWaveIn();
 		}

 		/// ------------------------------------------------------------------------------------
-		private void CloseWriter()
+		protected virtual void CloseWriter()
 		{
 			if (_writer != null)
 			{
@@ -102,7 +102,7 @@
 		}

 		/// ------------------------------------------------------------------------------------
-		private void CloseWaveIn()
+		protected virtual void CloseWaveIn()
 		{
 			if (_waveIn != null)
 			{
@@ -112,7 +112,7 @@
 			}
 		}

-		public WaveFormat RecordingFormat
+		public virtual WaveFormat RecordingFormat
 		{
 			get { return _recordingFormat; }
 			set
@@ -122,7 +122,7 @@
 			}
 		}

-		public void BeginMonitoring()
+		public virtual void BeginMonitoring()
 		{
 			Debug.Assert(_waveIn == null, "only call this once");
 			try
@@ -162,7 +162,7 @@
 		/// <summary>
 		/// as far as naudio is concerned, we are still "recording", but we aren't writing this file anymore
 		/// </summary>
-		void TransitionFromRecordingToMonitoring()
+		protected virtual void TransitionFromRecordingToMonitoring()
 		{
 			RecordedTime = TimeSpan.FromSeconds((double)_writer.Length / _writer.WaveFormat.AverageBytesPerSecond);
 			RecordingState = RecordingState.Monitoring;
@@ -182,12 +182,12 @@
 			Stopped(this, EventArgs.Empty);
 		}
 */
-		public void BeginRecording(string waveFileName)
+		public virtual void BeginRecording(string waveFileName)
 		{
 			BeginRecording(waveFileName, false);
 		}

-		public void BeginRecording(string waveFileName, bool appendToFile)
+		public virtual void BeginRecording(string waveFileName, bool appendToFile)
 		{
 			if (_recordingState != RecordingState.Monitoring)
 			{
@@ -212,7 +212,7 @@
 		}

 		/// ------------------------------------------------------------------------------------
-		private byte[] GetAudioBufferToAppendTo(string waveFileName)
+		protected virtual byte[] GetAudioBufferToAppendTo(string waveFileName)
 		{
 			using (var stream = new WaveFileReader(waveFileName))
 			{
@@ -227,7 +227,7 @@
 			}
 		}

-		public void Stop()
+		public virtual void Stop()
 		{
 			if (_recordingState == RecordingState.Recording)
 			{
@@ -238,7 +238,7 @@
 			TransitionFromRecordingToMonitoring();
 		}

-		private void TryGetVolumeControl()
+		protected virtual void TryGetVolumeControl()
 		{
 			int waveInDeviceNumber = _waveIn.DeviceNumber;
 			if (Environment.OSVersion.Version.Major >= 6) // Vista and over
@@ -283,36 +283,28 @@

 		}

-		public double MicrophoneLevel
-		{
-			get
-			{
-				return _microphoneLevel;
-			}
+		public virtual double MicrophoneLevel
+		{
+			get { return _microphoneLevel; }
 			set
 			{
 				_microphoneLevel = value;
 				if (_volumeControl != null)
-				{
 					_volumeControl.Percent = value;
-				}
-			}
-		}
-
-		public RecordingState RecordingState
-		{
-			get
-			{
-				return _recordingState;
-			}
-			private set
+			}
+		}
+
+		public virtual RecordingState RecordingState
+		{
+			get { return _recordingState; }
+			protected set
 			{
 				_recordingState = value;
 				Debug.WriteLine("recorder state--> " + value.ToString());
 			}
 		}

-		void waveIn_DataAvailable(object sender, WaveInEventArgs e)
+		protected virtual void waveIn_DataAvailable(object sender, WaveInEventArgs e)
 		{
  /*original from codeplex
   byte[] buffer = e.Buffer;
@@ -364,7 +356,7 @@
 			}
 		}

-		private void WriteToFile(byte[] buffer, int bytesRecorded)
+		protected virtual void WriteToFile(byte[] buffer, int bytesRecorded)
 		{
 			//REVIEW: why does this max time even exist?  I don't see that it affects buffer size
 			long maxFileLength = _recordingFormat.AverageBytesPerSecond * 60 * _maxMinutes;


eberhard: set the alternate email provider if no thunderbird or xdg-email

--- Palaso/Email/EmailProviderFactory.cs
+++ Palaso/Email/EmailProviderFactory.cs
@@ -28,7 +28,7 @@

 		public static IEmailProvider AlternateEmailProvider()
 		{
-			if (Environment.OSVersion.Platform == PlatformID.Unix)
+			if (Environment.OSVersion.Platform == PlatformID.Unix && !ThunderbirdIsDefault() && !File.Exists("/usr/bin/xdg-email"))
 			{
 				return null;
 			}
@@ -94,4 +94,4 @@
 		}

 	}
-}+}


Save layer file to a temporary file before loading it into the PixBuf.  Fixes an exception on .Net when the image gets too big.

[Fixes bug #594677]

--- Pinta.Core/ImageFormats/OraFormat.cs
+++ Pinta.Core/ImageFormats/OraFormat.cs
@@ -67,29 +67,50 @@
 				int y = int.Parse (GetAttribute (layerElement, "y", "0"));
 				string name = GetAttribute (layerElement, "name", string.Format ("Layer {0}", i));

-				Layer layer = layers.CreateLayer (name, width, height);
-				layers.Insert (layer, 0);
-				layer.Opacity = double.Parse (GetAttribute (layerElement, "opacity", "1"), GetFormat ());
-				Pixbuf pb = null;
-
 				try {
-					pb = new Pixbuf (file.GetInputStream (file.GetEntry (layerElement.GetAttribute ("src"))));
+					// Write the file to a temporary file first
+					// Fixes a bug when running on .Net
+					ZipEntry zf = file.GetEntry (layerElement.GetAttribute ("src"));
+					Stream s = file.GetInputStream (zf);
+					string tmp_file = System.IO.Path.GetTempFileName ();

-					using (Context g = new Context (layer.Surface)) {
-						CairoHelper.SetSourcePixbuf (g, pb, x, y);
-						g.Paint ();
+					using (Stream stream_out = File.Open (tmp_file, FileMode.OpenOrCreate)) {
+						byte[] buffer = new byte[2048];
+
+						while (true) {
+							int len = s.Read (buffer, 0, buffer.Length);
+
+							if (len > 0)
+								stream_out.Write (buffer, 0, len);
+							else
+								break;
+						}
 					}
+
+					Layer layer = layers.CreateLayer (name, width, height);
+					layers.Insert (layer, 0);
+					layer.Opacity = double.Parse (GetAttribute (layerElement, "opacity", "1"), GetFormat ());
+
+					using (Pixbuf pb = new Pixbuf (tmp_file)) {
+						using (Context g = new Context (layer.Surface)) {
+							CairoHelper.SetSourcePixbuf (g, pb, x, y);
+							g.Paint ();
+						}
+					}
+
+					try {
+						File.Delete (tmp_file);
+					} catch { }
 				} catch {
-					MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, "Could not import layer \"{0}\" from {0}", layer.Name, file);
+					MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, "Could not import layer \"{0}\" from {0}", name, file);
 					md.Title = "Error";

 					md.Run ();
 					md.Destroy ();
-				} finally {
-					if (pb != null)
-						(pb as IDisposable).Dispose ();
 				}
 			}
+
+			file.Close ();
 		}

 		private static IFormatProvider GetFormat () {


Update IConfigurableRasterFactory.cs

Update IConfigurableRasterFactory.cs

--- src/api/IConfigurableRasterFactory.cs
+++ src/api/IConfigurableRasterFactory.cs
@@ -1,14 +1,3 @@
-// Copyright 2011-2012 Green Code LLC
-// All rights reserved.
-//
-// The copyright holders license this file under the New (3-clause) BSD
-// License (the "License").  You may not use this file except in
-// compliance with the License.  A copy of the License is available at
-//
-//   http://www.opensource.org/licenses/BSD-3-Clause
-//
-// and is included in the NOTICE.txt file distributed with this work.
-//
 // Contributors:
 //   James Domingo, Green Code LLC


Fixed problems with GetComment

Fixed problems with GetComment

--- RedditSharp/Reddit.cs
+++ RedditSharp/Reddit.cs
@@ -192,6 +192,10 @@

         public Comment GetComment(string subreddit, string name, string linkName)
         {
+            if (linkName.StartsWith("t3_"))
+                linkName = linkName.Substring(3);
+            if (name.StartsWith("t1_"))
+                name = name.Substring(3);
             var request = CreateGet(string.Format(GetCommentUrl, subreddit, linkName, name), true);
             var response = request.GetResponse();
             var data = GetResponseString(response.GetResponseStream());


Limit the period with 30 secs min.

Limit the period with 30 secs min.

--- Route53DDNS/Runner.cs
+++ Route53DDNS/Runner.cs
@@ -45,6 +45,9 @@
                 {
                     logger.Warn("Initial delay is disabled. This is not recommended!");
                 }
+
+                long periodSec = opts.GeneralOptions.TimerPeriodSec < 30 ? 30 : opts.GeneralOptions.TimerPeriodSec;
+                periodSec *= 1000;
                 timer = new Timer(this.doIt, null, initialDelaySec * 1000, opts.GeneralOptions.TimerPeriodSec * 1000);
                 running = true;
             }


(ArchiveFileSystem): fixed directory traversal.

--- GameRes/FileSystem.cs
+++ GameRes/FileSystem.cs
@@ -319,15 +319,14 @@
         {
             if (string.IsNullOrEmpty (path))
                 return;
-            List<string> cur_dir;
+            var cur_dir = new List<string>();
             if (-1 != Array.IndexOf (m_path_delimiters, path[0]))
             {
                 path = path.TrimStart (m_path_delimiters);
-                cur_dir = new List<string>();
-            }
-            else
-            {
-                cur_dir = m_cwd.Split (m_path_delimiters).ToList();
+            }
+            else if (!string.IsNullOrEmpty (m_cwd))
+            {
+                cur_dir.AddRange (m_cwd.Split (m_path_delimiters));
             }
             var path_list = path.Split (m_path_delimiters);
             foreach (var dir in path_list)
@@ -392,6 +391,8 @@
                     Pop();
                     return;
                 }
+                Top.CurrentDirectory = entry.Name;
+                return;
             }
             if (entry.Name == LastVisitedPath && null != LastVisitedArc)
             {


Bumped version number

Bumped version number

--- GlobalAssemblyInfo.cs
+++ GlobalAssemblyInfo.cs
@@ -28,8 +28,8 @@
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.1.1.0")]
-[assembly: AssemblyFileVersion("2.1.1.0")]
+[assembly: AssemblyVersion("2.1.2.0")]
+[assembly: AssemblyFileVersion("2.1.2.0")]

 [assembly: CLSCompliant(false)]


removed file version attribute

removed file version attribute

--- GlobalAssemblyInfo.cs
+++ GlobalAssemblyInfo.cs
@@ -10,4 +10,3 @@
 [assembly: AssemblyCulture("")]

 [assembly: AssemblyVersion("0.1.2.0")]
-[assembly: AssemblyFileVersion("0.1.2.0")]


枠線の描画処理を修正

枠線の描画処理を修正

--- GraphicsExtensions.cs
+++ GraphicsExtensions.cs
@@ -53,17 +53,23 @@
         /// <summary>
         /// 指定した色、幅で枠線を描画します。
         /// </summary>
+        ///
+        /// <remarks>
+        /// TODO: ClipBounds の幅、高さで枠線を描画すると一部が切れてしまう。
+        /// 暫定的に margin を設定しているが、適切な描画方法について要調査。
+        /// </remarks>
         ///
         /* ----------------------------------------------------------------- */
         public static void DrawBorder(this Graphics gs, Color color, int width)
         {
             if (color == Color.Empty || width <= 0) return;

+            const float margin = 0.5f;
             using (var pen = new Pen(color, width))
             {
                 pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset;
                 var rect = gs.ClipBounds;
-                gs.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
+                gs.DrawRectangle(pen, rect.X, rect.Y, rect.Width - margin, rect.Height - margin);
             }
         }


More powerful factoring of common subexpressions

--- ComputerAlgebra/Extensions/Factor.cs
+++ ComputerAlgebra/Extensions/Factor.cs
@@ -7,6 +7,28 @@
 {
     public static class FactorExtension
     {
+        // Enumerates x, splitting negative constants into a positive constant and -1.
+        private static IEnumerable<Expression> FactorsOf(Expression x)
+        {
+            foreach (Expression i in Product.TermsOf(x))
+            {
+                if (i is Constant && (Real)i < 0)
+                {
+                    yield return -1;
+                    yield return Real.Abs((Real)i);
+                }
+                else if (i is Power)
+                {
+                    yield return i;
+                    yield return ((Power)i).Left;
+                }
+                else
+                {
+                    yield return i;
+                }
+            }
+        }
+
         /// <summary>
         /// Distribute products across sums.
         /// </summary>
@@ -42,15 +64,15 @@
                 IEnumerable<Expression> terms = s.Terms.Select(i => i.Factor()).Buffer();

                 // All of the distinct factors.
-                IEnumerable<Expression> factors = terms.SelectMany(i => Product.TermsOf(i)).Distinct();
+                IEnumerable<Expression> factors = terms.SelectMany(i => FactorsOf(i)).Distinct();
                 // Choose the most common factor to use.
-                Expression factor = factors.ArgMax(i => terms.Count(j => Product.TermsOf(j).Contains(i)));
+                Expression factor = factors.ArgMax(i => terms.Count(j => FactorsOf(j).Contains(i)));
                 // Find the terms that contain the factor.
-                IEnumerable<Expression> contains = terms.Where(i => Product.TermsOf(i).Contains(factor)).Buffer();
+                IEnumerable<Expression> contains = terms.Where(i => FactorsOf(i).Contains(factor)).Buffer();
                 // If more than one term contains the factor, pull it out and factor the resulting expression (again).
                 if (contains.Count() > 1)
                     return Sum.New(
-                        Product.New(factor, Sum.New(contains.Select(i => Product.New(Product.TermsOf(i).Except(factor)))).Evaluate()),
+                        Product.New(factor, Sum.New(contains.Select(i => Binary.Divide(i, factor))).Evaluate()),
                         Sum.New(terms.Except(contains, Expression.RefComparer))).Factor(null);
             }


fix nre - https://github.com/Inumedia/SlackAPI/issues/109

--- SlackAPI/Request.cs
+++ SlackAPI/Request.cs
@@ -9,6 +9,8 @@

 namespace SlackAPI
 {
+
+
     class RequestState<K>
         where K : Response
     {
@@ -69,7 +71,7 @@
         {
             try
             {
-                response = (HttpWebResponse)request.EndGetResponse(result);
+                response = (HttpWebResponse)request?.EndGetResponse(result);
                 Success = true;
             }
             catch (WebException we)
@@ -77,11 +79,8 @@
                 // If we don't get a response, let the exception bubble up as we can't do anything
                 if (we.Response == null)
                 {
-                    var defaultResponse = default(K);
-                    defaultResponse.ok = false;
-                    defaultResponse.error = we.ToString();
-                    if (callback != null)
-                        callback(defaultResponse);
+                    var defaultResponse = CreateDefaultResponseForError(we);
+                    callback?.Invoke((K)defaultResponse);
                     return;
                 }

@@ -89,19 +88,49 @@
                 response = (HttpWebResponse)we.Response;
                 //TODO: Handle timeouts, etc?
             }
-
+            catch (Exception e)
+            {
+                var defaultResponse = CreateDefaultResponseForError(e);
+                callback?.Invoke((K)defaultResponse);
+                return;
+            }

             K responseObj;
-
-            using (Stream responseReading = response.GetResponseStream())
-            using (StreamReader reader = new StreamReader(responseReading))
+            if (response == null)
             {
-                string responseData = reader.ReadToEnd();
-                responseObj = responseData.Deserialize<K>();
+                responseObj = (K)CreateDefaultResponseForError(new Exception("Empty response"));
+                callback?.Invoke(responseObj);
+                return;
             }

-            if(callback != null)
-                callback(responseObj);
+            try
+            {
+                using (Stream responseReading = response.GetResponseStream())
+                using (StreamReader reader = new StreamReader(responseReading))
+                {
+                    string responseData = reader.ReadToEnd();
+                    responseObj = responseData.Deserialize<K>();
+                }
+            }
+            catch (Exception e)
+            {
+                responseObj = (K)CreateDefaultResponseForError(e);
+            }
+
+            callback?.Invoke(responseObj);
+        }
+
+        private Response CreateDefaultResponseForError(Exception e)
+        {
+            var defaultResponse = new DefaultResponse();
+            defaultResponse.ok = false;
+            defaultResponse.error = e.ToString();
+            return defaultResponse;
+        }
+
+        class DefaultResponse: Response
+        {
+
         }
     }