Simplify the JSON tests for readability

Simplify the JSON tests for readability

Use ' instead of " in the expected JSON, then replace it before asserting.

--- csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
+++ csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
@@ -31,16 +31,16 @@
 #endregion

 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using Google.Protobuf.TestProtos;
 using NUnit.Framework;
 using UnitTest.Issues.TestProtos;

 namespace Google.Protobuf
 {
+    /// <summary>
+    /// Tests for the JSON formatter. Note that in these tests, double quotes are replaced with apostrophes
+    /// for the sake of readability (embedding \" everywhere is painful). See the AssertJson method for details.
+    /// </summary>
     public class JsonFormatterTest
     {
         [Test]
@@ -48,16 +48,16 @@
         {
             var formatter = new JsonFormatter(new JsonFormatter.Settings(formatDefaultValues: false));

-            Assert.AreEqual("{ }", formatter.Format(new ForeignMessage()));
-            Assert.AreEqual("{ }", formatter.Format(new TestAllTypes()));
-            Assert.AreEqual("{ }", formatter.Format(new TestMap()));
+            AssertJson("{ }", formatter.Format(new ForeignMessage()));
+            AssertJson("{ }", formatter.Format(new TestAllTypes()));
+            AssertJson("{ }", formatter.Format(new TestMap()));
         }

         [Test]
         public void DefaultValues_WhenIncluded()
         {
             var formatter = new JsonFormatter(new JsonFormatter.Settings(formatDefaultValues: true));
-            Assert.AreEqual("{ \"c\": 0 }", formatter.Format(new ForeignMessage()));
+            AssertJson("{ 'c': 0 }", formatter.Format(new ForeignMessage()));
         }

         [Test]
@@ -90,45 +90,45 @@
             };
             var actualText = JsonFormatter.Default.Format(message);

-            // Fields in declaration order, which matches numeric order.
+            // Fields in numeric order
             var expectedText = "{ " +
-                "\"singleInt32\": 100, " +
-                "\"singleInt64\": \"3210987654321\", " +
-                "\"singleUint32\": 4294967295, " +
-                "\"singleUint64\": \"18446744073709551615\", " +
-                "\"singleSint32\": -456, " +
-                "\"singleSint64\": \"-12345678901235\", " +
-                "\"singleFixed32\": 23, " +
-                "\"singleFixed64\": \"1234567890123\", " +
-                "\"singleSfixed32\": -123, " +
-                "\"singleSfixed64\": \"-12345678901234\", " +
-                "\"singleFloat\": 12.25, " +
-                "\"singleDouble\": 23.5, " +
-                "\"singleBool\": true, " +
-                "\"singleString\": \"test\\twith\\ttabs\", " +
-                "\"singleBytes\": \"AQIDBA==\", " +
-                "\"singleNestedMessage\": { \"bb\": 35 }, " +
-                "\"singleForeignMessage\": { \"c\": 10 }, " +
-                "\"singleImportMessage\": { \"d\": 20 }, " +
-                "\"singleNestedEnum\": \"FOO\", " +
-                "\"singleForeignEnum\": \"FOREIGN_BAR\", " +
-                "\"singleImportEnum\": \"IMPORT_BAZ\", " +
-                "\"singlePublicImportMessage\": { \"e\": 54 }" +
+                "'singleInt32': 100, " +
+                "'singleInt64': '3210987654321', " +
+                "'singleUint32': 4294967295, " +
+                "'singleUint64': '18446744073709551615', " +
+                "'singleSint32': -456, " +
+                "'singleSint64': '-12345678901235', " +
+                "'singleFixed32': 23, " +
+                "'singleFixed64': '1234567890123', " +
+                "'singleSfixed32': -123, " +
+                "'singleSfixed64': '-12345678901234', " +
+                "'singleFloat': 12.25, " +
+                "'singleDouble': 23.5, " +
+                "'singleBool': true, " +
+                "'singleString': 'test\\twith\\ttabs', " +
+                "'singleBytes': 'AQIDBA==', " +
+                "'singleNestedMessage': { 'bb': 35 }, " +
+                "'singleForeignMessage': { 'c': 10 }, " +
+                "'singleImportMessage': { 'd': 20 }, " +
+                "'singleNestedEnum': 'FOO', " +
+                "'singleForeignEnum': 'FOREIGN_BAR', " +
+                "'singleImportEnum': 'IMPORT_BAZ', " +
+                "'singlePublicImportMessage': { 'e': 54 }" +
                 " }";
-            Assert.AreEqual(expectedText, actualText);
+            AssertJson(expectedText, actualText);
         }

         [Test]
         public void RepeatedField()
         {
-            Assert.AreEqual("{ \"repeatedInt32\": [ 1, 2, 3, 4, 5 ] }",
+            AssertJson("{ 'repeatedInt32': [ 1, 2, 3, 4, 5 ] }",
                 JsonFormatter.Default.Format(new TestAllTypes { RepeatedInt32 = { 1, 2, 3, 4, 5 } }));
         }

         [Test]
         public void MapField_StringString()
         {
-            Assert.AreEqual("{ \"mapStringString\": { \"with spaces\": \"bar\", \"a\": \"b\" } }",
+            AssertJson("{ 'mapStringString': { 'with spaces': 'bar', 'a': 'b' } }",
                 JsonFormatter.Default.Format(new TestMap { MapStringString = { { "with spaces", "bar" }, { "a", "b" } } }));
         }

@@ -136,7 +136,7 @@
         public void MapField_Int32Int32()
         {
             // The keys are quoted, but the values aren't.
-            Assert.AreEqual("{ \"mapInt32Int32\": { \"0\": 1, \"2\": 3 } }",
+            AssertJson("{ 'mapInt32Int32': { '0': 1, '2': 3 } }",
                 JsonFormatter.Default.Format(new TestMap { MapInt32Int32 = { { 0, 1 }, { 2, 3 } } }));
         }

@@ -144,34 +144,34 @@
         public void MapField_BoolBool()
         {
             // The keys are quoted, but the values aren't.
-            Assert.AreEqual("{ \"mapBoolBool\": { \"false\": true, \"true\": false } }",
+            AssertJson("{ 'mapBoolBool': { 'false': true, 'true': false } }",
                 JsonFormatter.Default.Format(new TestMap { MapBoolBool = { { false, true }, { true, false } } }));
         }

         [TestCase(1.0, "1")]
-        [TestCase(double.NaN, "\"NaN\"")]
-        [TestCase(double.PositiveInfinity, "\"Infinity\"")]
-        [TestCase(double.NegativeInfinity, "\"-Infinity\"")]
+        [TestCase(double.NaN, "'NaN'")]
+        [TestCase(double.PositiveInfinity, "'Infinity'")]
+        [TestCase(double.NegativeInfinity, "'-Infinity'")]
         public void DoubleRepresentations(double value, string expectedValueText)
         {
             var message = new TestAllTypes { SingleDouble = value };
             string actualText = JsonFormatter.Default.Format(message);
-            string expectedText = "{ \"singleDouble\": " + expectedValueText + " }";
-            Assert.AreEqual(expectedText, actualText);
+            string expectedText = "{ 'singleDouble': " + expectedValueText + " }";
+            AssertJson(expectedText, actualText);
         }

         [Test]
         public void UnknownEnumValueOmitted_SingleField()
         {
             var message = new TestAllTypes { SingleForeignEnum = (ForeignEnum) 100 };
-            Assert.AreEqual("{ }", JsonFormatter.Default.Format(message));
+            AssertJson("{ }", JsonFormatter.Default.Format(message));
         }

         [Test]
         public void UnknownEnumValueOmitted_RepeatedField()
         {
             var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.FOREIGN_BAZ, (ForeignEnum) 100, ForeignEnum.FOREIGN_FOO } };
-            Assert.AreEqual("{ \"repeatedForeignEnum\": [ \"FOREIGN_BAZ\", \"FOREIGN_FOO\" ] }", JsonFormatter.Default.Format(message));
+            AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 'FOREIGN_FOO' ] }", JsonFormatter.Default.Format(message));
         }

         [Test]
@@ -179,7 +179,7 @@
         {
             // This matches the C++ behaviour.
             var message = new TestMap { MapInt32Enum = { { 1, MapEnum.MAP_ENUM_FOO }, { 2, (MapEnum) 100 }, { 3, MapEnum.MAP_ENUM_BAR } } };
-            Assert.AreEqual("{ \"mapInt32Enum\": { \"1\": \"MAP_ENUM_FOO\", \"3\": \"MAP_ENUM_BAR\" } }", JsonFormatter.Default.Format(message));
+            AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '3': 'MAP_ENUM_BAR' } }", JsonFormatter.Default.Format(message));
         }

         [Test]
@@ -188,14 +188,14 @@
             // *Maybe* we should hold off on writing the "[" until we find that we've got at least one value to write...
             // but this is what happens at the moment, and it doesn't seem too awful.
             var message = new TestAllTypes { RepeatedForeignEnum = { (ForeignEnum) 200, (ForeignEnum) 100 } };
-            Assert.AreEqual("{ \"repeatedForeignEnum\": [ ] }", JsonFormatter.Default.Format(message));
+            AssertJson("{ 'repeatedForeignEnum': [ ] }", JsonFormatter.Default.Format(message));
         }

         [Test]
         public void NullValueForMessage()
         {
             var message = new TestMap { MapInt32ForeignMessage = { { 10, null } } };
-            Assert.AreEqual("{ \"mapInt32ForeignMessage\": { \"10\": null } }", JsonFormatter.Default.Format(message));
+            AssertJson("{ 'mapInt32ForeignMessage': { '10': null } }", JsonFormatter.Default.Format(message));
         }

         [Test]
@@ -205,14 +205,14 @@
         public void SimpleNonAscii(string text, string encoded)
         {
             var message = new TestAllTypes { SingleString = text };
-            Assert.AreEqual("{ \"singleString\": \"" + encoded + "\" }", JsonFormatter.Default.Format(message));
+            AssertJson("{ 'singleString': '" + encoded + "' }", JsonFormatter.Default.Format(message));
         }

         [Test]
         public void SurrogatePairEscaping()
         {
             var message = new TestAllTypes { SingleString = "a\uD801\uDC01b" };
-            Assert.AreEqual("{ \"singleString\": \"a\\ud801\\udc01b\" }", JsonFormatter.Default.Format(message));
+            AssertJson("{ 'singleString': 'a\\ud801\\udc01b' }", JsonFormatter.Default.Format(message));
         }

         [Test]
@@ -241,8 +241,8 @@

         [Test]
         [TestCase(null, "{ }")]
-        [TestCase("x", "{ \"fooString\": \"x\" }")]
-        [TestCase("", "{ \"fooString\": \"\" }")]
+        [TestCase("x", "{ 'fooString': 'x' }")]
+        [TestCase("", "{ 'fooString': '' }")]
         [TestCase(null, "{ }")]
         public void Oneof(string fooStringValue, string expectedJson)
         {
@@ -254,9 +254,9 @@

             // We should get the same result both with and without "format default values".
             var formatter = new JsonFormatter(new JsonFormatter.Settings(false));
-            Assert.AreEqual(expectedJson, formatter.Format(message));
+            AssertJson(expectedJson, formatter.Format(message));
             formatter = new JsonFormatter(new JsonFormatter.Settings(true));
-            Assert.AreEqual(expectedJson, formatter.Format(message));
+            AssertJson(expectedJson, formatter.Format(message));
         }

         [Test]
@@ -271,8 +271,8 @@
                 BytesField = ByteString.FromBase64("ABCD"),
                 StringField = ""
             };
-            var expectedJson = "{ \"int64Field\": \"10\", \"int32Field\": 0, \"stringField\": \"\", \"bytesField\": \"ABCD\" }";
-            Assert.AreEqual(expectedJson, JsonFormatter.Default.Format(message));
+            var expectedJson = "{ 'int64Field': '10', 'int32Field': 0, 'stringField': '', 'bytesField': 'ABCD' }";
+            AssertJson(expectedJson, JsonFormatter.Default.Format(message));
         }

         [Test]
@@ -291,11 +291,11 @@
         {
             var formatter = new JsonFormatter(new JsonFormatter.Settings(false));
             var message = new TestJsonFieldOrdering { PlainString = "p1", PlainInt32 = 2 };
-            Assert.AreEqual("{ \"plainString\": \"p1\", \"plainInt32\": 2 }", formatter.Format(message));
+            AssertJson("{ 'plainString': 'p1', 'plainInt32': 2 }", formatter.Format(message));
             message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" };
-            Assert.AreEqual("{ \"plainString\": \"plain\", \"o2String\": \"o2\", \"plainInt32\": 10, \"o1Int32\": 5 }", formatter.Format(message));
+            AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32': 10, 'o1Int32': 5 }", formatter.Format(message));
             message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, PlainInt32 = 10, PlainString = "plain" };
-            Assert.AreEqual("{ \"plainString\": \"plain\", \"o1String\": \"\", \"plainInt32\": 10, \"o2Int32\": 0 }", formatter.Format(message));
+            AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32': 10, 'o2Int32': 0 }", formatter.Format(message));
         }

         [Test]
@@ -303,11 +303,22 @@
         {
             var formatter = new JsonFormatter(new JsonFormatter.Settings(true));
             var message = new TestJsonFieldOrdering();
-            Assert.AreEqual("{ \"plainString\": \"\", \"plainInt32\": 0 }", formatter.Format(message));
+            AssertJson("{ 'plainString': '', 'plainInt32': 0 }", formatter.Format(message));
             message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" };
-            Assert.AreEqual("{ \"plainString\": \"plain\", \"o2String\": \"o2\", \"plainInt32\": 10, \"o1Int32\": 5 }", formatter.Format(message));
+            AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32': 10, 'o1Int32': 5 }", formatter.Format(message));
             message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, PlainInt32 = 10, PlainString = "plain" };
-            Assert.AreEqual("{ \"plainString\": \"plain\", \"o1String\": \"\", \"plainInt32\": 10, \"o2Int32\": 0 }", formatter.Format(message));
+            AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32': 10, 'o2Int32': 0 }", formatter.Format(message));
+        }
+
+        /// <summary>
+        /// Checks that the actual JSON is the same as the expected JSON - but after replacing
+        /// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier
+        /// to read.
+        /// </summary>
+        private static void AssertJson(string expectedJsonWithApostrophes, string actualJson)
+        {
+            var expectedJson = expectedJsonWithApostrophes.Replace("'", "\"");
+            Assert.AreEqual(expectedJson, actualJson);
         }
     }
 }


added one more method for protocol test cases

--- test/Test/ProtocolTestBase.cs
+++ test/Test/ProtocolTestBase.cs
@@ -247,5 +247,44 @@
                 await server.StopAsync();
             }
         }
+
+
+        [Theory]
+        [InlineData(typeof(RegularHostConfigurator))]
+        [InlineData(typeof(SecureHostConfigurator))]
+        public virtual async Task TestBreakRequestByteByByte(Type hostConfiguratorType)
+        {
+            var hostConfigurator = CreateObject<IHostConfigurator>(hostConfiguratorType);
+
+            using (var server = CreateServer(hostConfigurator))
+            {
+                await server.StartAsync();
+
+                using (var socket = CreateClient())
+                {
+                    var socketStream = await hostConfigurator.GetClientStream(socket);
+
+                    using (var reader = new StreamReader(socketStream, Utf8Encoding, true))
+                    using (var writer = new ConsoleWriter(socketStream, Utf8Encoding, 1024 * 8))
+                    {
+                        var msg = Guid.NewGuid().ToString();
+                        var line = CreateRequest(msg);
+
+                        for (var i = 0; i < line.Length; i++)
+                        {
+                            writer.Write(line[i]);
+                            writer.Flush();
+                            await Task.Delay(100);
+                        }
+
+                        var receivedLine = await reader.ReadLineAsync();
+
+                        Assert.Equal(msg, receivedLine);
+                    }
+                }
+
+                await server.StopAsync();
+            }
+        }
     }
 }


Fix warning

Fix warning

--- ArchiSteamFarm/NLog/SteamTarget.cs
+++ ArchiSteamFarm/NLog/SteamTarget.cs
@@ -76,7 +76,7 @@
 			string? botName = BotName?.Render(logEvent);

 			if (!string.IsNullOrEmpty(botName)) {
-				bot = Bot.GetBot(botName);
+				bot = Bot.GetBot(botName!);

 				if (bot?.IsConnectedAndLoggedOn != true) {
 					return;


Cleaned up code so you no will get specific package if found otherwise the highest version possible

--- Assets/NuGet/Editor/NugetHelper.cs
+++ Assets/NuGet/Editor/NugetHelper.cs
@@ -970,27 +970,39 @@
             foreach (var source in packageSources.Where(s => s.IsEnabled))
             {
                 var foundPackage = source.GetSpecificPackage(packageId);
-                if (foundPackage != null)
-                {
-                    if (package == null)
-                    {
-                        // if another package hasn't been found yet, use the current found one
-                        LogVerbose("{0} {1} was found in {2}, and wanted {3}", foundPackage.Id, foundPackage.Version, source.Name, packageId.Version);
-                        package = foundPackage;
-                    }
-                    else
-                    {
-                        // another package has been found previously, but neither match identically
-                        if (foundPackage < package)
-                        {
-                            // use the new package if it's closer to the desired version
-                            LogVerbose("{0} {1} was found in {2}, but wanted {3}", foundPackage.Id, foundPackage.Version, source.Name, packageId.Version);
-                            package = foundPackage;
-                        }
-                    }
-                }
-            }
-
+                if (foundPackage == null)
+                {
+                    continue;
+                }
+
+                if (foundPackage.Version == packageId.Version)
+                {
+                    LogVerbose("{0} {1} was found in {2}", foundPackage.Id, foundPackage.Version);
+                    return foundPackage;
+                }
+
+                LogVerbose("{0} {1} was found in {2}, but wanted {3}", foundPackage.Id, foundPackage.Version, source.Name, packageId.Version);
+                if (package == null)
+                {
+                    // if another package hasn't been found yet, use the current found one
+                    package = foundPackage;
+                }
+                // another package has been found previously, but neither match identically
+                else if (foundPackage > package)
+                {
+                    // use the new package if it's closer to the desired version
+                    package = foundPackage;
+                }
+            }
+            if (package != null)
+            {
+                LogVerbose("{0} {1} not found, using {2}", packageId.Id, packageId.Version, package.Version);
+            }
+            else
+            {
+                LogVerbose("Failed to find {0} {1}", packageId.Id, packageId.Version);
+            }
+
             return package;
         }


Adding some more Debug Mode changes.

Adding some more Debug Mode changes.

--- Assets/Scripts/SelectionManager.cs
+++ Assets/Scripts/SelectionManager.cs
@@ -78,6 +78,10 @@
 						unit.maxHealth = 3;
 						unit.attackCooldown = 3f;
 						unit.attackPower = 1;
+						unit.level = 1;
+						unit.previousLevel = 1;
+						unit.isSelected = false;
+						unit.isDirected = false;
 					}
 					NavMeshAgent agent = obj.GetComponent<NavMeshAgent>();
 					if (agent != null) {


remove unnecessary unityengine reference

--- Assets/UnTest/Editor/TestRunner.cs
+++ Assets/UnTest/Editor/TestRunner.cs
@@ -15,7 +15,6 @@
 using System.Diagnostics;

 using Object = System.Object;
-using Debug = UnityEngine.Debug;

 namespace UnTest {


Subscribes to emotion event, when emotion results return during a future problem, this page will invoke the quiz model to determine if problem generation needs to occur.

--- CITS/OrderOfOperationsPage.xaml.cs
+++ CITS/OrderOfOperationsPage.xaml.cs
@@ -41,6 +41,8 @@
             set;
         }

+
+        private event EventHandler<ConfidenceEventArgs> ResultsScreenDataReady;

@@ -61,11 +63,16 @@
             this.ProblemContentPage = new ProblemPage();
             this.ProblemContentPage.SolutionSubmitted += CheckIfNewProblem;
             this.ProblemContentPage.HintRequested += HintRequested;
+            this.ProblemContentPage.ConfidenceResultsReturned += EvaluateConfidence;

             this.ResultsContentPage = new ResultsPage();

             //Subscribe to page's close event
             this.ResultsContentPage.ResultsScreenDismissed += QuizCompleted;
+
+            //When Emotion request from last problem is done, update results
+            //page with average confidence level for quiz.
+            ResultsScreenDataReady += this.ResultsContentPage.UpdateConfidence;
             UpdateProblemPageWithProblem();

         //   await Navigation.PushModalAsync(this.ResultsContentPage);
@@ -92,25 +99,30 @@
             //Check if answer is correct
             if(MathProblems.Peek().IsSolutionCorrect(this.ProblemContentPage.Solution))
             {
+                quiz.WasPreviousAnswerCorrect = true;
                 quiz.NumberOfCorrectAnswers++;
             }
             else
             {
-                if(ProblemGenerator.rng.Next(0,2) == 1)
-                {
-                    generateNewProblem = true;
-                }
-            }
+                quiz.WasPreviousAnswerCorrect = false;
+            }
+            //else
+            //{
+            //    if(ProblemGenerator.rng.Next(0,2) == 1)
+            //    {
+            //        generateNewProblem = true;
+            //    }
+            //}

             //Remove currently answered problem
             MathProblems.Dequeue();

-            if(generateNewProblem)
-            {
-                var newProblemQueue = quiz.GenerateMathProblems(1);
-                MathProblems.Enqueue(newProblemQueue.Dequeue());
-                quiz.NumberOfGeneratedProblems++;
-            }
+            //if(generateNewProblem)
+            //{
+            //    var newProblemQueue = quiz.GenerateMathProblems(1);
+            //    MathProblems.Enqueue(newProblemQueue.Dequeue());
+            //    quiz.NumberOfGeneratedProblems++;
+            //}
             UpdateProblemPageWithProblem();

 		}
@@ -171,6 +183,9 @@
                 this.ResultsContentPage.ResultsSummary =
                         $"You answered {quiz.NumberOfCorrectAnswers} out of {quiz.NumberOfProblems} problems correctly!";
                 this.ResultsContentPage.NumberOfGeneratedProblems = pluralizeProblemString;
+
+                var recommendation = quiz.GetRecommendation();
+                this.ResultsContentPage.Recommendation = recommendation;
                 this.ResultsContentPage.UpdatePage();

                 //Clear this text so that when the modal view is switching
@@ -190,10 +205,44 @@
 				}
                 this.PreviousSessionLabel.Text =
                     $"Last Session Results: {quiz.NumberOfCorrectAnswers} correct out of {quiz.NumberOfProblems}";
-                this.RecommendationLabel.Text = quiz.GetRecommendation();
+                this.RecommendationLabel.Text = recommendation;

 			}
+        }
+
+        private void EvaluateConfidence(object sender, EmotionEventArgs e)
+        {
+            /* The quiz instance lives within this class (not ProblemPage.xaml.cs)
+            so increment the number of times emotion values have been analyzed
+            for the quiz class object.  This is not always 1:1 with the number
+            of answered problems because a bad picture may be taken with no results.
+             */
+            quiz.AddEmotionsForLastSolvedProblem(e.Anger, e.Contempt, e.Disgust,
+                                                 e.Fear, e.Happiness, e.Neutral,
+                                                 e.Sadness, e.Surprise);
+
+            //If the last math problem has been solved, then the results screen
+            //is being shown and we do not need to generate the last problem.
+            if(MathProblems.Count != 0)
+			{
+			    if(!quiz.WasPreviousAnswerCorrect /*&& quiz.GenerateNewProblemBasedOnConfidence(e)*/)
+			    {
+					var newProblemQueue = quiz.GenerateMathProblems(1);
+					MathProblems.Enqueue(newProblemQueue.Dequeue());
+					quiz.NumberOfGeneratedProblems++;
+			    }
+			}
+            else
+            {
+                /* This means the results screen is showing, so raise event letting
+                   the results screen know that the average confidence has been
+                   returned and calculated.
+                 */
+                ResultsScreenDataReady(this,new ConfidenceEventArgs(quiz.ConfidenceAverage));
+
+            }
+
         }
     }
 }


Added a crude catch which prints to stdout to avoid crashing the server entirely if a request somehow fails

--- Ceen.Httpd.Cli/AppDomainHandler.cs
+++ Ceen.Httpd.Cli/AppDomainHandler.cs
@@ -155,7 +155,14 @@
 			/// <param name="logtaskid">The task ID to use.</param>
 			public void HandleRequest(SocketInformation socket, EndPoint remoteEndPoint, string logtaskid)
 			{
-				m_handleRequest.Invoke(m_wrapped, new object[] { socket, remoteEndPoint, logtaskid });
+				try
+				{
+					m_handleRequest.Invoke(m_wrapped, new object[] { socket, remoteEndPoint, logtaskid });
+				}
+				catch (Exception ex)
+				{
+					Console.WriteLine("Failed to process request: {0}", ex);
+				}
 			}

 			/// <summary>


Wildcard test.

Wildcard test.

--- ChapterTests/03/QueryParserTest.cs
+++ ChapterTests/03/QueryParserTest.cs
@@ -17,6 +17,25 @@
         [Fact]
         public void TestWildcards()
         {
+            using (var directory = new RAMDirectory())
+            {
+                IndexSingleFieldDocs(directory, new[] {
+                    new Field("contents", "wild", Field.Store.YES, Field.Index.ANALYZED),
+                    new Field("contents", "child", Field.Store.YES, Field.Index.ANALYZED),
+                    new Field("contents", "mild", Field.Store.YES, Field.Index.ANALYZED),
+                    new Field("contents", "mildew", Field.Store.YES, Field.Index.ANALYZED)
+                });
+
+                using (var indexSearcher = new IndexSearcher(directory))
+                {
+                    var query = new WildcardQuery(new Term("contents", "?ild*"));
+                    var topDocs = indexSearcher.Search(query, 10);
+                    Assert.Equal(3, topDocs.TotalHits); // "child no match"
+                    Assert.Equal(topDocs.ScoreDocs[0].Score, topDocs.ScoreDocs[1].Score, 1); // "score the same"
+                    Assert.Equal(topDocs.ScoreDocs[1].Score, topDocs.ScoreDocs[2].Score, 1); // "score the same"
+                }
+            }
+
         }

     }


Delete MetaExpression.cs

Delete MetaExpression.cs

--- csp/BaseTypes/MetaExpression.cs
+++ csp/BaseTypes/MetaExpression.cs
@@ -1,18 +0,0 @@
-/*
-  Copyright © Iain McDonald 2010-2019
-
-  This file is part of Decider.
-
-  Unlike the Expression type which is wholly supported on its own, the MetaExpression relies
-  on the values of other supporting variables. Thus, if those variables change, the bounds
-  of the MetaExpression need to be re-evaluated.
-*/
-using System.Collections.Generic;
-
-namespace Decider.Csp.BaseTypes
-{
-	public interface IMetaExpression<T>
-	{
-		IList<IVariable<T>> Support { get; }
-	}
-}


Handling errors without xml response

Handling errors without xml response

--- CodeBase/mite.net/MiteException.cs
+++ CodeBase/mite.net/MiteException.cs
@@ -70,26 +70,36 @@

         internal static MiteException CreateFromResponse(string response, Exception innerException)
         {
-            XmlDocument xmlDocument = new XmlDocument();
-            xmlDocument.LoadXml(response);
+            MiteException miteException;

-            MiteException miteException = new MiteException();
+            if (response.StartsWith(@"<?xml version=""1.0"" encoding=""UTF-8""?>"))
+            {
+                miteException = new MiteException(innerException.Message, innerException);

-            XmlNodeList errorNodes = xmlDocument.SelectNodes("/errors/error");
+                XmlDocument xmlDocument = new XmlDocument();

-            foreach (XmlNode errorNode in errorNodes)
+                xmlDocument.LoadXml(response);
+
+                XmlNodeList errorNodes = xmlDocument.SelectNodes("/errors/error");
+
+                foreach (XmlNode errorNode in errorNodes)
+                {
+                    MiteError miteError = new MiteError(errorNode.InnerText);
+                    XmlAttribute propertyAttribute = errorNode.Attributes["on"];
+
+                    if (propertyAttribute != null)
+                    {
+                        miteError.Property = propertyAttribute.Value;
+                    }
+
+                    miteException.Errors.Add(miteError);
+                }
+            }
+            else
             {
-               MiteError miteError = new MiteError(errorNode.InnerText);
-               XmlAttribute propertyAttribute =  errorNode.Attributes["on"];
-
-                if (propertyAttribute != null)
-                {
-                    miteError.Property = propertyAttribute.Value;
-                }
-
-                miteException.Errors.Add(miteError);
+                miteException = new MiteException(response, innerException);
             }
-
+
             return miteException;
         }
     }


Feat(RemoveWebPart): homogeneity of documentation

--- Commands/WebParts/RemoveWebPart.cs
+++ Commands/WebParts/RemoveWebPart.cs
@@ -12,12 +12,12 @@
     [CmdletHelp("Removes a webpart from a page",
         Category = CmdletHelpCategory.WebParts)]
     [CmdletExample(
-        Code = @"PS:> Remove-PnPWebPartToWikiPage -ServerRelativePageUrl ""/sites/demo/sitepages/home.aspx"" -Identity a2875399-d6ff-43a0-96da-be6ae5875f82",
-        Remarks = @"This will remove the webpart as defined by the XML in the listview.webpart file to the specified page in the first row and the first column of the HTML table present on the page",
+        Code = @"PS:> Remove-PnPWebPart -ServerRelativePageUrl ""/sites/demo/sitepages/home.aspx"" -Identity a2875399-d6ff-43a0-96da-be6ae5875f82",
+        Remarks = @"This will remove the webpart specified by ID to the specified page in the first row and the first column of the HTML table present on the page",
         SortOrder = 1)]
     [CmdletExample(
-        Code = @"PS:> Remove-PnPWebPartToWikiPage -ServerRelativePageUrl ""/sites/demo/sitepages/home.aspx"" -Name MyWebpart",
-        Remarks = @"This will remove the webpart as defined by the XML in the listview.webpart file to the specified page in the first row and the first column of the HTML table present on the page",
+        Code = @"PS:> Remove-PnPWebPart -ServerRelativePageUrl ""/sites/demo/sitepages/home.aspx"" -Title MyWebpart",
+        Remarks = @"This will remove the webpart specified by title to the specified page in the first row and the first column of the HTML table present on the page",
         SortOrder = 1)]
     public class RemoveWebPart : PnPWebCmdlet
     {
@@ -28,7 +28,7 @@
         [Alias("Name")]
         public string Title = string.Empty;

-        [Parameter(Mandatory = true, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Full server relative url of the webpart page, e.g. /sites/demo/sitepages/home.aspx")]
+        [Parameter(Mandatory = true, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Server relative url of the webpart page, e.g. /sites/demo/sitepages/home.aspx")]
         [Alias("PageUrl")]
         public string ServerRelativePageUrl = string.Empty;


Only if serialize serviceable if serviceable = true, because older NuGet servers couldn't handle the serviceable attribute

--- Core/Authoring/ManifestMetadata.cs
+++ Core/Authoring/ManifestMetadata.cs
@@ -111,6 +111,16 @@

         [XmlElement("serviceable")]
         public bool Serviceable { get; set; }
+
+        /// <summary>
+        /// Serialize <see cref="Serviceable"/>?
+        /// Only if <see cref="Serviceable"/> is <c>true</c>, because older NuGet servers couldn't handle the serviceable attribute
+        /// </summary>
+        /// <returns></returns>
+        public bool ShouldSerializeServiceable()
+        {
+            return Serviceable;
+        }

         /// <summary>
         /// This property should be used only by the XML serializer. Do not use it in code.


Fix Denial of Service with bad UPnP responses (#387)

--- neo/Network/UPnP.cs
+++ neo/Network/UPnP.cs
@@ -34,28 +34,32 @@
             s.SendTo(data, ipe);

             byte[] buffer = new byte[0x1000];
+
             do
             {
                 int length;
                 try
                 {
                     length = s.Receive(buffer);
+
+                    string resp = Encoding.ASCII.GetString(buffer, 0, length).ToLower();
+                    if (resp.Contains("upnp:rootdevice"))
+                    {
+                        resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9);
+                        resp = resp.Substring(0, resp.IndexOf("\r")).Trim();
+                        if (!string.IsNullOrEmpty(_serviceUrl = GetServiceUrl(resp)))
+                        {
+                            return true;
+                        }
+                    }
                 }
-                catch (SocketException)
+                catch
                 {
                     continue;
                 }
-                string resp = Encoding.ASCII.GetString(buffer, 0, length).ToLower();
-                if (resp.Contains("upnp:rootdevice"))
-                {
-                    resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9);
-                    resp = resp.Substring(0, resp.IndexOf("\r")).Trim();
-                    if (!string.IsNullOrEmpty(_serviceUrl = GetServiceUrl(resp)))
-                    {
-                        return true;
-                    }
-                }
-            } while (DateTime.Now - start < TimeOut);
+            }
+            while (DateTime.Now - start < TimeOut);
+
             return false;
         }


BuildPackage for Unity

BuildPackage for Unity

--- core/UnityPackage/Assets/Editor/PackageBuilder.cs
+++ core/UnityPackage/Assets/Editor/PackageBuilder.cs
@@ -4,6 +4,13 @@
 {
     [MenuItem("Assets/Build UnityPackage")]
     public static void BuildPackage()
+    {
+        BuildPackageCore();
+        BuildPackageFull();
+    }
+
+    [MenuItem("Assets/Build UnityPackage (Core)")]
+    public static void BuildPackageCore()
     {
         var assetPaths = new string[]
         {


Restrict scoping on methods.

Restrict scoping on methods.

--- cslacs/Csla/Core/FieldManager/FieldDataManager.cs
+++ cslacs/Csla/Core/FieldManager/FieldDataManager.cs
@@ -13,8 +13,6 @@
   [Serializable()]
   public class FieldDataManager : IUndoableObject
   {
-    private static Dictionary<Type, List<IPropertyInfo>> _consolidatedLists = new Dictionary<Type, List<IPropertyInfo>>();
-
     [NonSerialized()]
     private List<IPropertyInfo> _propertyList;
     private IFieldData[] _fieldData;
@@ -34,7 +32,23 @@
       _propertyList = GetConsolidatedList(businessObjectType);
     }

-    private List<IPropertyInfo> GetConsolidatedList(Type type)
+    /// <summary>
+    /// Returns a copy of the property list for
+    /// the business object. Returns
+    /// null if there are no properties registered
+    /// for this object.
+    /// </summary>
+    public List<IPropertyInfo> GetRegisteredProperties()
+    {
+      return new List<IPropertyInfo>(_propertyList);
+    }
+
+
+    #region ConsolidatedPropertyList
+
+    private static Dictionary<Type, List<IPropertyInfo>> _consolidatedLists = new Dictionary<Type, List<IPropertyInfo>>();
+
+    private static List<IPropertyInfo> GetConsolidatedList(Type type)
     {
       List<IPropertyInfo> result = null;
       if (!_consolidatedLists.TryGetValue(type, out result))
@@ -51,7 +65,7 @@
       return result;
     }

-    private List<IPropertyInfo> CreateConsolidatedList(Type type)
+    private static List<IPropertyInfo> CreateConsolidatedList(Type type)
     {
       List<IPropertyInfo> result = new List<IPropertyInfo>();
       // get inheritance hierarchy
@@ -83,6 +97,8 @@
       return result;
     }

+    #endregion
+
     #region  Get/Set/Find fields

     /// <summary>
@@ -92,7 +108,7 @@
     /// <param name="prop">
     /// The property corresponding to the field.
     /// </param>
-    public IFieldData GetFieldData(IPropertyInfo prop)
+    internal IFieldData GetFieldData(IPropertyInfo prop)
     {
       return _fieldData[prop.Index];
     }
@@ -123,7 +139,7 @@
     /// <param name="value">
     /// Value to store for field.
     /// </param>
-    public void SetFieldData<P>(IPropertyInfo prop, P value)
+    internal void SetFieldData<P>(IPropertyInfo prop, P value)
     {
       var field = _fieldData[prop.Index];
       if (field == null)
@@ -151,7 +167,7 @@
     /// <param name="value">
     /// Value to store for field.
     /// </param>
-    public IFieldData LoadFieldData<P>(IPropertyInfo prop, P value)
+    internal IFieldData LoadFieldData<P>(IPropertyInfo prop, P value)
     {
       var field = _fieldData[prop.Index];
       if (field == null)
@@ -176,7 +192,7 @@
     /// <param name="prop">
     /// The property corresponding to the field.
     /// </param>
-    public void RemoveField(IPropertyInfo prop)
+    internal void RemoveField(IPropertyInfo prop)
     {
       var field = _fieldData[prop.Index];
       if (field != null)
@@ -195,25 +211,7 @@
     {
       return _fieldData[propertyInfo.Index] != null;
     }
-
-    /// <summary>
-    /// Returns a list of all child objects
-    /// contained in the list of fields.
-    /// </summary>
-    /// <remarks>
-    /// This method returns a list of actual child
-    /// objects, not a list of
-    /// <see cref="IFieldData" /> container objects.
-    /// </remarks>
-    public List<object> GetChildren()
-    {
-      List<object> result = new List<object>();
-      foreach (var item in _fieldData)
-        if (item != null && (item.Value is IEditableBusinessObject || item.Value is IEditableCollection))
-          result.Add(item.Value);
-      return result;
-    }
-
+
     #endregion

     #region  IsValid/IsDirty
@@ -246,7 +244,7 @@
     /// Marks all fields as clean
     /// (not dirty).
     /// </summary>
-    public void MarkClean()
+    internal void MarkClean()
     {
       foreach (var item in _fieldData)
         if (item != null && item.IsDirty)
@@ -371,7 +369,26 @@

     #endregion

-    #region  Update Children
+    #region  Child Objects
+
+
+    /// <summary>
+    /// Returns a list of all child objects
+    /// contained in the list of fields.
+    /// </summary>
+    /// <remarks>
+    /// This method returns a list of actual child
+    /// objects, not a list of
+    /// <see cref="IFieldData" /> container objects.
+    /// </remarks>
+    public List<object> GetChildren()
+    {
+      List<object> result = new List<object>();
+      foreach (var item in _fieldData)
+        if (item != null && (item.Value is IEditableBusinessObject || item.Value is IEditableCollection))
+          result.Add(item.Value);
+      return result;
+    }

     /// <summary>
     /// Invokes the data portal to update


Use HTTPS endpoiont

Use HTTPS endpoiont

--- src/ErgastiApi/Client/ErgastClient.cs
+++ src/ErgastiApi/Client/ErgastClient.cs
@@ -11,7 +11,7 @@
 {
     public class ErgastClient : IDisposable, IErgastClient
     {
-        private string _apiRoot = "http://ergast.com/api/f1";
+        private string _apiRoot = "https://ergast.com/api/f1";

         private JsonSerializerSettings SerializerSettings { get; } = new JsonSerializerSettings { ContractResolver = new JsonPathContractResolver() };


Fix pubsub test.

Fix pubsub test.

--- pubsub/api/PubsubTest/PubsubTest.cs
+++ pubsub/api/PubsubTest/PubsubTest.cs
@@ -176,7 +176,7 @@
             permissions.Add("pubsub.subscriptions.update");
             TestIamPermissionsRequest request = new TestIamPermissionsRequest
             {
-                Resource = new TopicName(_projectId, subscriptionId).ToString(),
+                Resource = new SubscriptionName(_projectId, subscriptionId).ToString(),
                 Permissions = { permissions }
             };
             TestIamPermissionsResponse response = publisher.TestIamPermissions(request);


Added For without generics so can pass over type

--- src/AutoMapper.Collection/AutoMapper.Collection.EntityFramework/Extensions.cs
+++ src/AutoMapper.Collection/AutoMapper.Collection.EntityFramework/Extensions.cs
@@ -1,4 +1,8 @@
-using System.Data.Entity;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data.Entity;
+using AutoMapper.QueryableExtensions.Impl;

 namespace AutoMapper.EntityFramework
 {
@@ -15,5 +19,21 @@
         {
             return new Persistance<TSource>(source, Mapper.Engine);
         }
+
+        /// <summary>
+        /// Non Generic call for For
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="destType"></param>
+        /// <returns></returns>
+        public static IEnumerable For<TSource>(this IQueryDataSourceInjection<TSource> source, Type destType)
+        {
+            var forMethod = source.GetType().GetMethod("For").MakeGenericMethod(destType);
+            var listType = typeof(List<>).MakeGenericType(destType);
+            var forResult = forMethod.Invoke(source, new object[] { null });
+            var enumeratedResult = Activator.CreateInstance(listType, forResult);
+            return enumeratedResult as IEnumerable;
+        }
     }
 }


SboApp fix (GetExecutingAssembly)

SboApp fix (GetExecutingAssembly)

--- src/ITCO.SboAddon.Framework/SboApp.cs
+++ src/ITCO.SboAddon.Framework/SboApp.cs
@@ -55,7 +55,7 @@
                 var connectResponse = _diCompany.Connect();
                 ErrorHelper.HandleErrorWithException(connectResponse, "DI API Could not connect");

-                var assemblyName = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;
+                var assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
                 _application.StatusBar.SetText($"{assemblyName} connected to SBO", SAPbouiCOM.BoMessageTime.bmt_Short, SAPbouiCOM.BoStatusBarMessageType.smt_Success);

                 SetAppEvents();


Don't do hit testing for resize when we are maximized

--- src/ControlzEx/Behaviors/WindowChrome/WindowChromeBehavior.MessageHandling.cs
+++ src/ControlzEx/Behaviors/WindowChrome/WindowChromeBehavior.MessageHandling.cs
@@ -500,8 +500,10 @@
             var mousePosScreen = Utility.GetPoint(lParam);
             var windowRect = this._GetWindowRect();

-            var ht = this._HitTestNca(DpiHelper.DeviceRectToLogical(windowRect, dpi.DpiScaleX, dpi.DpiScaleY),
-                                      DpiHelper.DevicePixelsToLogical(mousePosScreen, dpi.DpiScaleX, dpi.DpiScaleY));
+            var ht = this._GetHwndState() == WindowState.Maximized
+                ? HT.CLIENT
+                : this._HitTestNca(DpiHelper.DeviceRectToLogical(windowRect, dpi.DpiScaleX, dpi.DpiScaleY),
+                                   DpiHelper.DevicePixelsToLogical(mousePosScreen, dpi.DpiScaleX, dpi.DpiScaleY));

             if (ht != HT.CLIENT
                 || this.AssociatedObject.ResizeMode == ResizeMode.CanResizeWithGrip)


Disable timestamp check for now

Disable timestamp check for now

--- src/DeploymentCockpit.BusinessLogic/ScriptExecution/TargetCommandProcessor.cs
+++ src/DeploymentCockpit.BusinessLogic/ScriptExecution/TargetCommandProcessor.cs
@@ -43,8 +43,8 @@
                     var json = EncryptionHelper.Decrypt(encryptedJson, encriptionKey, encriptionSalt);

                     var command = JsonConvert.DeserializeObject<ScriptExecutionCommand>(json);
-                    if (command.CommandTime.AddSeconds(60) < DateTime.UtcNow)
-                        throw new TimeoutException();  // To prevent re-execution of script by using sniffed packet.
+                    // if (command.CommandTime.AddSeconds(60) < DateTime.UtcNow)
+                    //     throw new TimeoutException();  // To prevent re-execution of script by using sniffed packet.
 #if DEBUG
                     Console.WriteLine("Executing {0} script.", command.ScriptType);
 #endif


-SwaggerIgnorePropertyAttribute.cs

-SwaggerIgnorePropertyAttribute.cs

--- src/Eurofurence.App.Domain.Model/Attributes/SwaggerIgnorePropertyAttribute.cs
+++ src/Eurofurence.App.Domain.Model/Attributes/SwaggerIgnorePropertyAttribute.cs
@@ -1,8 +0,0 @@
-using System;
-
-namespace Eurofurence.App.Domain.Model.Attributes
-{
-    public class SwaggerIgnorePropertyAttribute : Attribute
-    {
-    }
-}


[Fixes #4204] React to changes in Localization.

--- src/Microsoft.AspNetCore.Mvc.Localization/Internal/MvcLocalizationServices.cs
+++ src/Microsoft.AspNetCore.Mvc.Localization/Internal/MvcLocalizationServices.cs
@@ -17,8 +17,15 @@
             Action<LocalizationOptions> setupAction)
         {
             AddMvcLocalizationServices(services, format, setupAction);
-
-            services.AddLocalization(setupAction);
+
+            if (setupAction == null)
+            {
+                services.AddLocalization();
+            }
+            else
+            {
+                services.AddLocalization(setupAction);
+            }
         }

         // To enable unit testing only 'MVC' specific services


remove useless context interface (#4993)

--- src/Microsoft.DocAsCode.MarkdigEngine.Validators/IMarkdownValidatorContext.cs
+++ src/Microsoft.DocAsCode.MarkdigEngine.Validators/IMarkdownValidatorContext.cs
@@ -1,12 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-namespace Microsoft.DocAsCode.MarkdigEngine.Validators
-{
-    public interface IMarkdownValidatorContext
-    {
-        string GlobalRulesFilePath { get; }
-
-        string CustomRulesFilePath { get; }
-    }
-}


Added DrawLineArrowInternal method

Added DrawLineArrowInternal method

--- dependencies/Renderer.PdfSharp-wpf/PdfRenderer.cs
+++ dependencies/Renderer.PdfSharp-wpf/PdfRenderer.cs
@@ -250,7 +250,7 @@
             }
         }

-        private void DrawLineArrowsInternal(XGraphics _gfx, Core2D.Shapes.XLine line, double dx, double dy, out XPoint pt1, out XPoint pt2)
+        private void DrawLineArrowsInternal(XGraphics gfx, Core2D.Shapes.XLine line, double dx, double dy, out XPoint pt1, out XPoint pt2)
         {
             XSolidBrush fillStartArrow = ToXSolidBrush(line.Style.StartArrowStyle.Fill);
             XPen strokeStartArrow = ToXPen(line.Style.StartArrowStyle, _scaleToPage);
@@ -275,105 +275,66 @@
             double a1 = Math.Atan2(y1 - y2, x1 - x2) * 180.0 / Math.PI;
             double a2 = Math.Atan2(y2 - y1, x2 - x1) * 180.0 / Math.PI;

-            var t1 = new XMatrix();
-            var c1 = new XPoint(x1, y1);
-            t1.RotateAtPrepend(a1, c1);
-
-            var t2 = new XMatrix();
-            var c2 = new XPoint(x2, y2);
-            t2.RotateAtPrepend(a2, c2);
-
-            double radiusX1 = sas.RadiusX;
-            double radiusY1 = sas.RadiusY;
-            double sizeX1 = 2.0 * radiusX1;
-            double sizeY1 = 2.0 * radiusY1;
-
-            switch (sas.ArrowType)
+            // Draw start arrow.
+            pt1 = DrawLineArrowInternal(gfx, strokeStartArrow, fillStartArrow, x1, y1, a1, sas);
+
+            // Draw end arrow.
+            pt2 = DrawLineArrowInternal(gfx, strokeEndArrow, fillEndArrow, x2, y2, a2, eas);
+        }
+
+        private static XPoint DrawLineArrowInternal(XGraphics gfx, XPen pen, XSolidBrush brush, double x, double y, double angle, Core2D.Style.ArrowStyle style)
+        {
+            XPoint pt;
+            var rt = new XMatrix();
+            var c = new XPoint(x, y);
+            rt.RotateAtPrepend(angle, c);
+            double rx = style.RadiusX;
+            double ry = style.RadiusY;
+            double sx = 2.0 * rx;
+            double sy = 2.0 * ry;
+
+            switch (style.ArrowType)
             {
                 default:
                 case Core2D.Style.ArrowType.None:
                     {
-                        pt1 = new XPoint(x1, y1);
+                        pt = new XPoint(x, y);
                     }
                     break;
                 case Core2D.Style.ArrowType.Rectangle:
                     {
-                        pt1 = t1.Transform(new XPoint(x1 - sizeX1, y1));
-                        var rect = new XRect(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1);
-                        _gfx.Save();
-                        _gfx.RotateAtTransform(a1, c1);
-                        DrawRectangleInternal(_gfx, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect);
-                        _gfx.Restore();
+                        pt = rt.Transform(new XPoint(x - sx, y));
+                        var rect = new XRect(x - sx, y - ry, sx, sy);
+                        gfx.Save();
+                        gfx.RotateAtTransform(angle, c);
+                        DrawRectangleInternal(gfx, brush, pen, style.IsStroked, style.IsFilled, ref rect);
+                        gfx.Restore();
                     }
                     break;
                 case Core2D.Style.ArrowType.Ellipse:
                     {
-                        pt1 = t1.Transform(new XPoint(x1 - sizeX1, y1));
-                        _gfx.Save();
-                        _gfx.RotateAtTransform(a1, c1);
-                        var rect = new XRect(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1);
-                        DrawEllipseInternal(_gfx, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect);
-                        _gfx.Restore();
+                        pt = rt.Transform(new XPoint(x - sx, y));
+                        gfx.Save();
+                        gfx.RotateAtTransform(angle, c);
+                        var rect = new XRect(x - sx, y - ry, sx, sy);
+                        DrawEllipseInternal(gfx, brush, pen, style.IsStroked, style.IsFilled, ref rect);
+                        gfx.Restore();
                     }
                     break;
                 case Core2D.Style.ArrowType.Arrow:
                     {
-                        pt1 = t1.Transform(new XPoint(x1, y1));
-                        var p11 = t1.Transform(new XPoint(x1 - sizeX1, y1 + sizeY1));
-                        var p21 = t1.Transform(new XPoint(x1, y1));
-                        var p12 = t1.Transform(new XPoint(x1 - sizeX1, y1 - sizeY1));
-                        var p22 = t1.Transform(new XPoint(x1, y1));
-                        DrawLineInternal(_gfx, strokeStartArrow, sas.IsStroked, ref p11, ref p21);
-                        DrawLineInternal(_gfx, strokeStartArrow, sas.IsStroked, ref p12, ref p22);
+                        pt = rt.Transform(new XPoint(x, y));
+                        var p11 = rt.Transform(new XPoint(x - sx, y + sy));
+                        var p21 = rt.Transform(new XPoint(x, y));
+                        var p12 = rt.Transform(new XPoint(x - sx, y - sy));
+                        var p22 = rt.Transform(new XPoint(x, y));
+                        DrawLineInternal(gfx, pen, style.IsStroked, ref p11, ref p21);
+                        DrawLineInternal(gfx, pen, style.IsStroked, ref p12, ref p22);
                     }
                     break;
             }

-            double radiusX2 = eas.RadiusX;
-            double radiusY2 = eas.RadiusY;
-            double sizeX2 = 2.0 * radiusX2;
-            double sizeY2 = 2.0 * radiusY2;
-
-            switch (eas.ArrowType)
-            {
-                default:
-                case Core2D.Style.ArrowType.None:
-                    {
-                        pt2 = new XPoint(x2, y2);
-                    }
-                    break;
-                case Core2D.Style.ArrowType.Rectangle:
-                    {
-                        pt2 = t2.Transform(new XPoint(x2 - sizeX2, y2));
-                        var rect = new XRect(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2);
-                        _gfx.Save();
-                        _gfx.RotateAtTransform(a2, c2);
-                        DrawRectangleInternal(_gfx, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect);
-                        _gfx.Restore();
-                    }
-                    break;
-                case Core2D.Style.ArrowType.Ellipse:
-                    {
-                        pt2 = t2.Transform(new XPoint(x2 - sizeX2, y2));
-                        _gfx.Save();
-                        _gfx.RotateAtTransform(a2, c2);
-                        var rect = new XRect(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2);
-                        DrawEllipseInternal(_gfx, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect);
-                        _gfx.Restore();
-                    }
-                    break;
-                case Core2D.Style.ArrowType.Arrow:
-                    {
-                        pt2 = t2.Transform(new XPoint(x2, y2));
-                        var p11 = t2.Transform(new XPoint(x2 - sizeX2, y2 + sizeY2));
-                        var p21 = t2.Transform(new XPoint(x2, y2));
-                        var p12 = t2.Transform(new XPoint(x2 - sizeX2, y2 - sizeY2));
-                        var p22 = t2.Transform(new XPoint(x2, y2));
-                        DrawLineInternal(_gfx, strokeEndArrow, eas.IsStroked, ref p11, ref p21);
-                        DrawLineInternal(_gfx, strokeEndArrow, eas.IsStroked, ref p12, ref p22);
-                    }
-                    break;
-            }
+            return pt;
         }

         private static void DrawRectangleInternal(XGraphics gfx, XSolidBrush brush, XPen pen, bool isStroked, bool isFilled, ref XRect rect)


Fixed api parameters

Fixed api parameters

if no 'api-version' parameter presents in url path all parameter are removed. Only one 'api-version' parameter exists on swagger document page.

--- src/SwashbuckleAspNetVersioningShim/RemoveVersionParametersOperationFilter.cs
+++ src/SwashbuckleAspNetVersioningShim/RemoveVersionParametersOperationFilter.cs
@@ -20,17 +20,19 @@
                 }
                 else
                 {
-                    var parameters = new List<IParameter> {
-                        new NonBodyParameter()
-                        {
-                            Name = "api-version",
-                            Required = true,
-                            Default = apiVersion.ToString(),
-                            In = "query",
-                            Type = "string"
-                        }
-                    };
-                    operation.Parameters = parameters;
+                    var versionParameterInQuery = operation?.Parameters?.SingleOrDefault(p => p.Name == "api-version" && p.In == "query");
+                    if (versionParameterInQuery != null)
+                    {
+                        operation.Parameters.Remove(versionParameterInQuery);
+                    }
+                    operation?.Parameters?.Add(new NonBodyParameter()
+                    {
+                        Name = "api-version",
+                        Required = true,
+                        Default = apiVersion.ToString(),
+                        In = "query",
+                        Type = "string"
+                    });
                 }
             }
         }


Remove debugging code

Remove debugging code

--- src/System.Diagnostics.Tracing/tests/BasicEventSourceTest/TestEventCounter.cs
+++ src/System.Diagnostics.Tracing/tests/BasicEventSourceTest/TestEventCounter.cs
@@ -235,7 +235,6 @@
                         if (num100msecTimerTicks > 3)       // We seem to have problems with timer events going off 100% reliably.  To avoid failures here we only check if in the 700 msec test we get at least 3 100 msec ticks.
                             Assert.True(8 <= evts.Count, $"FAILURE: 8 <= {evts.Count}");
                         Assert.True(evts.Count <= 32, $"FAILURE: {evts.Count} <= 32");
-                        Assert.Equal(3, 4);
                     }));


Added the rest of the unit tests for model field value (single value)

--- src/TestStack.Seleno.Tests/PageObjects/Actions/Fields/ModelFieldValueTests.cs
+++ src/TestStack.Seleno.Tests/PageObjects/Actions/Fields/ModelFieldValueTests.cs
@@ -64,14 +64,29 @@
             TestSpec("Boolean", modelValue, expectedIsTrueValue, expectedValue);
         }

-        [TestCase(1, false, "1")]
-        [TestCase(2.3, false, "2.3")]
-        [TestCase(2.333f, false, "2.333")]
-        [TestCase(2.3355551111111, false, "2.3355551111111")]
-        [TestCase((short)5, false, "5")]
-        public void NumericTests(object modelValue, bool expectedIsTrueValue, string expectedValue)
+        [TestCase(1, "1")]
+        [TestCase(2.3, "2.3")]
+        [TestCase(2.333f, "2.333")]
+        [TestCase(2.3355551111111, "2.3355551111111")]
+        [TestCase((short)5, "5")]
+        public void NumericTests(object modelValue, string expectedValue)
         {
-            TestSpec("Numeric", modelValue, expectedIsTrueValue, expectedValue);
+            TestSpec("Numeric", modelValue, false, expectedValue);
+        }
+
+        [TestCase(null, "")]
+        [TestCase(2, "2")]
+        public void NullableIntTests(int? modelValue, string expectedValue)
+        {
+            TestSpec("Nullable Int", modelValue, false, expectedValue);
+        }
+
+        [TestCase(null, "")]
+        [TestCase("", "")]
+        [TestCase("asdf", "asdf")]
+        public void StringTests(string modelValue, string expectedValue)
+        {
+            TestSpec("String", modelValue, false, expectedValue);
         }
     }
 }


fixed merge conflicts

fixed merge conflicts

--- src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs
+++ src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs
@@ -931,7 +931,7 @@
             private IBidirectionalMap<SourceTextContainer, DocumentId> _sourceTextContainersToDocumentIds = BidirectionalMap<SourceTextContainer, DocumentId>.Empty;

             /// <summary>
-            /// the map of <see cref="DocumentId"/> to <see cref="IDynamicFileInfoProvider"/> whose <see cref="DynamicFileInfo"/> got added into <see cref="Workspace"/>
+            /// The map of <see cref="DocumentId"/> to <see cref="IDynamicFileInfoProvider"/> whose <see cref="DynamicFileInfo"/> got added into <see cref="Workspace"/>
             /// </summary>
             private readonly Dictionary<DocumentId, IDynamicFileInfoProvider> _documentIdToDynamicFileInfoProvider = new Dictionary<DocumentId, IDynamicFileInfoProvider>();


Testsite project no longer needs access to inernals

--- src/JSNLog/Properties/AssemblyInfo.cs
+++ src/JSNLog/Properties/AssemblyInfo.cs
@@ -27,19 +27,11 @@
 // http://stackoverflow.com/questions/36141302/why-is-it-recommended-to-include-the-private-key-used-for-assembly-signing-in-op
 [assembly: AssemblyKeyFileAttribute("../jsnlog.strongname.snk")]

-//
-
-
+// Allow project JSNLog.Tests to access the internals of this project. Public key is needed because JSNLog has a strong name.
 [assembly: InternalsVisibleTo("JSNLog.Tests, PublicKey=" +
     "002400000480000094000000060200000024000052534131000400000100010015488505fd9c86" +
     "9dfb9af3ee7d980a24f9a379fbea34c6311b481f77688c74fae162335ae47a8ef800bfd83c1795" +
     "97ab12c86278065bd9cbc1997863f5bc4a2f03b5a519e0b7097edb5649e7d982b94f7d6c8ef60d" +
     "35f79aaf9785d1f79d5bc0c529edc38fb99dc88cb7475d32946286b0766b3bc32bc4bd9871768f" +
     "70ea49ba")]
-[assembly: InternalsVisibleTo("JSNLog.TestSite, PublicKey=" +
-    "002400000480000094000000060200000024000052534131000400000100010015488505fd9c86" +
-    "9dfb9af3ee7d980a24f9a379fbea34c6311b481f77688c74fae162335ae47a8ef800bfd83c1795" +
-    "97ab12c86278065bd9cbc1997863f5bc4a2f03b5a519e0b7097edb5649e7d982b94f7d6c8ef60d" +
-    "35f79aaf9785d1f79d5bc0c529edc38fb99dc88cb7475d32946286b0766b3bc32bc4bd9871768f" +
-    "70ea49ba")]


Adapt index too low test to consider the fact that the EnumerableAccessor isn't even applicable to indices lower than 0

--- test/Pather.CSharp.UnitTests/ResolverTests.cs
+++ test/Pather.CSharp.UnitTests/ResolverTests.cs
@@ -115,13 +115,13 @@
         }

         [Fact]
-        public void ArrayIndexResolution_IndexLower_FailWithIndexTooLow()
+        public void ArrayIndexResolution_IndexLower_FailWithNoApplicablePathElementType()
         {
             var r = new Resolver();
             var array = new[] { "1", "2" };
             var path = "[-2]";

-            r.Invoking(re => re.Resolve(array, path)).ShouldThrow<IndexOutOfRangeException>();
+            r.Invoking(re => re.Resolve(array, path)).ShouldThrow<InvalidOperationException>();
         }
     }
 }


Record which packages were missing if we skipped an installed instance

If you are missing a package in your install, we wouldn't say which one
was missing so you got to figure it out the hard way. This will now
log it so you can fix your install.

--- src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstanceFactory.cs
+++ src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstanceFactory.cs
@@ -272,15 +272,17 @@
                 return isMatch;
             });

-            var instanceFoundWithInvalidState = false;
+            var messages = new List<string>();

             foreach (ISetupInstance2 instance in instances)
             {
-                var packages = instance.GetPackages()
-                                       .Where((package) => requiredPackageIds.Contains(package.GetId()));
-
-                if (packages.Count() != requiredPackageIds.Count())
-                {
+                var instancePackagesIds = instance.GetPackages().Select(p => p.GetId()).ToHashSet();
+                var missingPackageIds = requiredPackageIds.Where(p => !instancePackagesIds.Contains(p)).ToList();
+
+                if (missingPackageIds.Count > 0)
+                {
+                    messages.Add($"An instance of {instance.GetDisplayName()} at {instance.GetInstallationPath()} was found but was missing these packages: " +
+                        string.Join(", ", missingPackageIds));
                     continue;
                 }

@@ -288,18 +290,16 @@

                 var state = instance.GetState();

-                if ((state & minimumRequiredState) == minimumRequiredState)
-                {
-                    return instance;
-                }
-
-                Debug.WriteLine($"An instance matching the specified requirements but had an invalid state. (State: {state})");
-                instanceFoundWithInvalidState = true;
-            }
-
-            throw new Exception(instanceFoundWithInvalidState ?
-                                "An instance matching the specified requirements was found but it was in an invalid state." :
-                                "There were no instances of Visual Studio found that match the specified requirements.");
+                if ((state & minimumRequiredState) != minimumRequiredState)
+                {
+                    messages.Add($"An instance of {instance.GetDisplayName()} at {instance.GetInstallationPath()} matched the specified requirements but had an invalid state. (State: {state})");
+                    continue;
+                }
+
+                return instance;
+            }
+
+            throw new Exception(string.Join(Environment.NewLine, messages));
         }

         private static Process StartNewVisualStudioProcess(string installationPath, int majorVersion)


danger - delete button

danger - delete button

--- BForms.Docs/Areas/Demo/Views/Contributors/Grid/_Actions.cshtml
+++ BForms.Docs/Areas/Demo/Views/Contributors/Grid/_Actions.cshtml
@@ -6,7 +6,7 @@
     <button class="btn btn-default js-btn-enable_selected" style="display:none" title="Export selected to excel">@Html.BsGlyphicon(Glyphicon.DownloadAlt)</button>
     <button class="btn btn-default js-btn-enable_selected" style="display:none" title="Enable selected">@Html.BsGlyphicon(Glyphicon.Ok)</button>
     <button class="btn btn-default js-btn-disable_selected" style="display:none" title="Disable selected">@Html.BsGlyphicon(Glyphicon.Remove)</button>
-    <button class="btn btn-default js-btn-delete_selected" style="display:none" title="Delete selected">@Html.BsGlyphicon(Glyphicon.Trash)</button>
+    <button class="btn btn-danger js-btn-delete_selected" style="display:none" title="Delete selected">@Html.BsGlyphicon(Glyphicon.Trash)</button>

         <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"></button>


Ensure completionapi experiment does not interfere with integration tests

--- src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstanceFactory.cs
+++ src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstanceFactory.cs
@@ -11,6 +11,7 @@
 using System.Threading.Tasks;
 using EnvDTE;
 using Microsoft.VisualStudio.Setup.Configuration;
+using Microsoft.Win32;
 using RunTests;
 using Process = System.Diagnostics.Process;

@@ -327,6 +328,15 @@
                 // Disable background download UI to avoid toasts
                 Process.Start(vsRegEditExeFile, $"set \"{installationPath}\" {Settings.Default.VsRootSuffix} HKCU \"FeatureFlags\\Setup\\BackgroundDownload\" Value dword 0").WaitForExit();

+                // Remove legacy experiment setting for controlling async completion to ensure it does not interfere.
+                // We no longer set this value, but it could be in place from an earlier test run on the same machine.
+                var disabledFlights = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\ABExp\LocalTest", "DisabledFlights", Array.Empty<string>()) as string[] ?? Array.Empty<string>();
+                if (disabledFlights.Any(flight => string.Equals(flight, "completionapi", StringComparison.OrdinalIgnoreCase)))
+                {
+                    disabledFlights = disabledFlights.Where(flight => !string.Equals(flight, "completionapi", StringComparison.OrdinalIgnoreCase)).ToArray();
+                    Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\ABExp\LocalTest", "DisabledFlights", disabledFlights, RegistryValueKind.MultiString);
+                }
+
                 // Disable text editor error reporting because it pops up a dialog. We want to either fail fast in our
                 // custom handler or fail silently and continue testing.
                 Process.Start(vsRegEditExeFile, $"set \"{installationPath}\" {Settings.Default.VsRootSuffix} HKCU \"Text Editor\" \"Report Exceptions\" dword 0").WaitForExit();


Also update the interface.

Also update the interface.

--- src/Magick.NET/Shared/IMagickImage.cs
+++ src/Magick.NET/Shared/IMagickImage.cs
@@ -4050,6 +4050,14 @@
         void Threshold(Percentage percentage);

         /// <summary>
+        /// Threshold image.
+        /// </summary>
+        /// <param name="percentage">The threshold percentage.</param>
+        /// <param name="channels">The channel(s) that should be thresholded.</param>
+        /// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
+        void Threshold(Percentage percentage, Channels channels);
+
+        /// <summary>
         /// Resize image to thumbnail size.
         /// <para />
         /// Resize will fit the image into the requested size. It does NOT fill, the requested box size.


Adding acceptance tests

Adding acceptance tests

--- test/unit-tests/TestModularInputsDebugging.cs
+++ test/unit-tests/TestModularInputsDebugging.cs
@@ -50,6 +50,9 @@
                 </input>");
             _stdout = new StringWriter();
             _stderr = new StringWriter();
+            ModularInput._stdin = _stdin;
+            ModularInput._stdout = _stdout;
+            ModularInput._stderr = _stderr;
         }

@@ -176,13 +179,36 @@
             Assert.True(checkedIsAttached);
         }

-        public async Task ShouldRunTheInput()
-        {
-
+
+        [Trait("unit-test", "Splunk.ModularInputs.ModularInput")]
+        [Fact]
+        public async Task ShouldInvokeRunAsyncWhenRunIsCalled()
+        {
+            ModularInput.Run<TestDebugInput>(new string[0]);
+            Assert.True(TestDebugInput.Executed);
+        }
+
+        [Trait("unit-test", "Splunk.ModularInputs.ModularInput")]
+        [Fact]
+        public async Task ShouldThrowExceptionWhenRunIsCalledIfTimeIsZeroAndAttachPointsWereSet()
+        {
+            Assert.Throws<ArgumentOutOfRangeException>(() =>
+            {
+                ModularInput.Run<TestDebugInput>(new string[0], DebuggerAttachPoints.StreamEvents, 0);
+            });
+        }
+
+        [Trait("unit-test", "Splunk.ModularInputs.ModularInput")]
+        [Fact]
+        public async Task ShouldNotThrowExceptionWhenRunIsCalledIfTimeIsZeroAndAttachPointsWereNotSet()
+        {
+            ModularInput.Run<TestDebugInput>(new string[0], DebuggerAttachPoints.None, 0);
         }

         public class TestDebugInput : ModularInput
         {
+            public static bool Executed = false;
+
             public override Scheme Scheme
             {
                 get { throw new NotImplementedException(); }
@@ -190,6 +216,7 @@

             public override Task StreamEventsAsync(InputDefinition inputDefinition, EventWriter eventWriter)
             {
+                Executed = true;
                 return Task.FromResult(false);
             }
         }


Tried benchmarks with netcoreapp2.2 - strangely now the results meet expectations of cpu and memory


add aggregates

add aggregates

--- src/Namster/Services/SearchService.cs
+++ src/Namster/Services/SearchService.cs
@@ -44,18 +44,16 @@
         public async Task<ISearchResponse<DataNam>> FindByMatchAsync(string term, int size)
         {
             var baseSearch =
-                Query<DataNam>.MultiMatch(
-                    m =>
-                        m.OnFields(f => f.NamNumber, f => f.Building, f => f.Room,
-                            f => f.Department, f => f.Division).Query(term));
+                Query<DataNam>.MultiMatch(m =>
+                    m.OnFields(f => f.NamNumber, f => f.Building, f => f.Room,
+                        f => f.Department, f => f.Division).Query(term));

-            return
-                await
-                    _client.SearchAsync<DataNam>(
-                        s =>
-                            s.Size(size)
-                                .Query(baseSearch)
-                                .Highlight(_highlightDescription));
+            return await _client.SearchAsync<DataNam>(s =>
+                s.Size(size)
+                    .Query(baseSearch)
+                    .Aggregations(a =>
+                        a.Terms("Building", d => d.Field(f => f.ExactBuilding)))
+                    .Highlight(_highlightDescription));
         }
     }
 }


fix #1350 added new columns in the cat nodes API

--- src/Nest/Domain/Cat/CatNodesRecord.cs
+++ src/Nest/Domain/Cat/CatNodesRecord.cs
@@ -63,6 +63,14 @@
 		internal string _diskAvail { get; set; }
 		public string DiskAvailable { get { return this._diskAvail ?? this._disk ?? this._d ?? this._disk_avail; }}

+		[JsonProperty("heap.current")]
+		internal string _heap_current { get; set; }
+		[JsonProperty("hc")]
+		internal string _hc { get; set; }
+		[JsonProperty("heapCurrent")]
+		internal string _heapCurrent { get; set; }
+		public string HeapCurrent { get { return this._heapCurrent ?? this._hc ?? this._heap_current; }}
+
 		[JsonProperty("heap.percent")]
 		internal string _heap_percent { get; set; }
 		[JsonProperty("hp")]
@@ -78,6 +86,14 @@
 		[JsonProperty("heapMax")]
 		internal string _heapMax { get; set; }
 		public string HeapMax { get { return this._heapMax ?? this._hm ?? this._heap_max; }}
+]
+		[JsonProperty("ram.current")]
+		internal string _ram_current { get; set; }
+		[JsonProperty("rc")]
+		internal string _rc { get; set; }
+		[JsonProperty("ramCurrent")]
+		internal string _ramCurrent { get; set; }
+		public string RamCurrent { get { return this._ramCurrent ?? this._rc ?? this._ram_current; }}

 		[JsonProperty("ram.percent")]
 		internal string _ram_percent { get; set; }
@@ -187,6 +203,22 @@
 		internal string _flushTotalTime { get; set; }
 		public string FlushTotalTime { get { return this._flushTotalTime ?? this._ftt ?? this._flush_total_time; }}

+		[JsonProperty("file_desc.percent")]
+		internal int _file_desc_percent { get; set; }
+		[JsonProperty("fdp")]
+		internal int _fdp { get; set; }
+		[JsonProperty("fileDescriptorPercent")]
+		internal int _fileDescriptorPercent { get; set; }
+		public int FileDescriptorPercent { get { return this._fileDescriptorPercent ?? this._fdp ?? this._file_desc_percent; }}
+
+		[JsonProperty("file_desc.max")]
+		internal int _file_desc_max { get; set; }
+		[JsonProperty("fdm")]
+		internal int _fdm { get; set; }
+		[JsonProperty("fileDescriptorMax")]
+		internal int _fileDescriptorMax { get; set; }
+		public int FileDescriptorMax { get { return this._fileDescriptorMax ?? this._fdm ?? this._file_desc_max; }}
+
 		[JsonProperty("get.current")]
 		internal string _get_current { get; set; }
 		[JsonProperty("gc")]


Add snippet for Deconstruct (#1423)

Add snippet for Deconstruct (#1423)

--- src/NodaTime.Demo/DateIntervalDemo.cs
+++ src/NodaTime.Demo/DateIntervalDemo.cs
@@ -69,5 +69,40 @@
             var result = Snippet.For(interval.Contains(june));
             Assert.AreEqual(true, result);
         }
+
+        [Test]
+        public void Deconstruction()
+        {
+            LocalDate start = new LocalDate(2017, 1, 1);
+            LocalDate end = new LocalDate(2017, 12, 31);
+
+            DateInterval value = new DateInterval(start, end);
+
+            Snippet.SilentForAction(() => value.Deconstruct(out var _, out var _));
+            value.Deconstruct(out LocalDate actualStart, out LocalDate actualEnd);
+
+            Assert.AreEqual(start, actualStart);
+            Assert.AreEqual(end, actualEnd);
+        }
+
+        [Test]
+        public void Union()
+        {
+            DateInterval firstInterval = new DateInterval(
+                new LocalDate(2014, 3, 7),
+                new LocalDate(2014, 3, 20));
+
+            DateInterval secondInterval = new DateInterval(
+                new LocalDate(2014, 3, 15),
+                new LocalDate(2014, 3, 23));
+
+            DateInterval? overlappingInterval = Snippet.For(firstInterval.Union(secondInterval));
+
+            Assert.AreEqual(
+                new DateInterval(
+                    new LocalDate(2014, 3, 7),
+                    new LocalDate(2014, 3, 23)),
+                overlappingInterval);
+        }
     }
 }


Improve Preconditions efficiency

Improve Preconditions efficiency

This significantly improves the Duration.From* performance, but
isn't quite good enough to let us remove the manual optimizations in
the LocalTime constructor and
GregorianYearMonthDayCalculator.ValidateGregorianYearMonthDay.

If we could hook into the build process and rewrite the Roslyn tree,
we could perform those optimizations automatically, and even remove
the explicit Preconditions calls entirely, putting everything in
attributes. We're not there yet though :(

--- src/NodaTime/Utility/Preconditions.cs
+++ src/NodaTime/Utility/Preconditions.cs
@@ -43,17 +43,22 @@
 #endif
         }

+        // Note: this overload exists for performance reasons. It would be reasonable to call the
+        // version using "long" values, but we'd incur conversions on every call. This method
+        // may well be called very often.
+        internal static void CheckArgumentRange([InvokerParameterName] string paramName, int value, int minInclusive, int maxInclusive)
+        {
+            if (value < minInclusive || value > maxInclusive)
+            {
+                ThrowArgumentOutOfRangeException(paramName, value, minInclusive, maxInclusive);
+            }
+        }
+
         internal static void CheckArgumentRange([InvokerParameterName] string paramName, long value, long minInclusive, long maxInclusive)
         {
             if (value < minInclusive || value > maxInclusive)
             {
-#if PCL
-                throw new ArgumentOutOfRangeException(paramName,
-                    $"Value should be in range [{minInclusive}-{maxInclusive}]");
-#else
-                throw new ArgumentOutOfRangeException(paramName, value,
-                    $"Value should be in range [{minInclusive}-{maxInclusive}]");
-#endif
+                ThrowArgumentOutOfRangeException(paramName, value, minInclusive, maxInclusive);
             }
         }

@@ -61,31 +66,14 @@
         {
             if (value < minInclusive || value > maxInclusive || double.IsNaN(value))
             {
-#if PCL
-                throw new ArgumentOutOfRangeException(paramName,
-                    $"Value should be in range [{minInclusive}-{maxInclusive}]");
-#else
-                throw new ArgumentOutOfRangeException(paramName, value,
-                    $"Value should be in range [{minInclusive}-{maxInclusive}]");
-#endif
+                ThrowArgumentOutOfRangeException(paramName, value, minInclusive, maxInclusive);
             }
         }

-        // Note: this overload exists for performance reasons. It would be reasonable to call the
-        // version using "long" values, but we'd incur conversions on every call. This method
-        // may well be called very often.
-        internal static void CheckArgumentRange([InvokerParameterName] string paramName, int value, int minInclusive, int maxInclusive)
+        private static void ThrowArgumentOutOfRangeException<T>([InvokerParameterName] string paramName, T value, T minInclusive, T maxInclusive)
         {
-            if (value < minInclusive || value > maxInclusive)
-            {
-#if PCL
-                throw new ArgumentOutOfRangeException(paramName,
-                    $"Value should be in range [{minInclusive}-{maxInclusive}]");
-#else
-                throw new ArgumentOutOfRangeException(paramName, value,
-                    $"Value should be in range [{minInclusive}-{maxInclusive}]");
-#endif
-            }
+            throw new ArgumentOutOfRangeException(paramName, value,
+                $"Value should be in range [{minInclusive}-{maxInclusive}]");
         }

         /// <summary>


Fix rpc deadlock when exception is thrown inside of PerformRemoteProcedureCallAsync. (#70)

--- src/POGOLib.Official/Net/RpcClient.cs
+++ src/POGOLib.Official/Net/RpcClient.cs
@@ -449,29 +449,33 @@
             return Task.Run(async () =>
             {
                 _rpcQueue.Enqueue(requestEnvelope);
-
-                RpcQueueMutex.WaitOne();
-
-                RequestEnvelope processRequestEnvelope;
-                while (_rpcQueue.TryDequeue(out processRequestEnvelope))
-                {
-                    var diff = Math.Max(0, DateTime.Now.Millisecond - LastRpcRequest.Millisecond);
-                    if (diff < Configuration.ThrottleDifference)
-                    {
-                        var delay = Configuration.ThrottleDifference - diff + (int) (_session.Random.NextDouble()*0);
-
-                        await Task.Delay(delay);
+
+                try
+                {
+                    RpcQueueMutex.WaitOne();
+
+                    RequestEnvelope processRequestEnvelope;
+                    while (_rpcQueue.TryDequeue(out processRequestEnvelope))
+                    {
+                        var diff = Math.Max(0, DateTime.Now.Millisecond - LastRpcRequest.Millisecond);
+                        if (diff < Configuration.ThrottleDifference)
+                        {
+                            var delay = Configuration.ThrottleDifference - diff + (int)(_session.Random.NextDouble() * 0);
+
+                            await Task.Delay(delay);
+                        }
+
+                        _rpcResponses.GetOrAdd(processRequestEnvelope, await PerformRemoteProcedureCallAsync(processRequestEnvelope));
                     }
-
-                    _rpcResponses.GetOrAdd(processRequestEnvelope, await PerformRemoteProcedureCallAsync(processRequestEnvelope));
-                }
-
-                ByteString ret;
-                _rpcResponses.TryRemove(requestEnvelope, out ret);
-
-                RpcQueueMutex.Release();
-
-                return ret;
+
+                    ByteString ret;
+                    _rpcResponses.TryRemove(requestEnvelope, out ret);
+                    return ret;
+                }
+                finally
+                {
+                    RpcQueueMutex.Release();
+                }
             });
         }


Remove commented line

Remove commented line

--- src/Polly.Shared/Retry/RetrySyntax.cs
+++ src/Polly.Shared/Retry/RetrySyntax.cs
@@ -128,7 +128,6 @@
         {
             if (onRetry == null) throw new ArgumentNullException(nameof(onRetry));

-            //return policyBuilder.RetryForever((outcome, ctx) => onRetry(outcome));
             return policyBuilder.RetryForever((Exception outcome, Context ctx) => onRetry(outcome));
         }


Create props sync, execute async

Create props sync, execute async

Rather than having the method itself being async.

--- src/RawRabbit/Operations/Responder.cs
+++ src/RawRabbit/Operations/Responder.cs
@@ -72,7 +72,7 @@

 		private Task SendResponseAsync<TResponse>(TResponse result, BasicDeliverEventArgs requestPayload)
 		{
-			var propsTask = CreateReplyPropsAsync(requestPayload);
+			var propsTask = Task.Run(() => CreateReplyProps(requestPayload));
 			var serializeTask = Task.Run(() => Serializer.Serialize(result));

 			return Task
@@ -90,16 +90,12 @@
 				});
 		}

-		private static Task<IBasicProperties> CreateReplyPropsAsync(BasicDeliverEventArgs requestPayload)
+		private static IBasicProperties CreateReplyProps(BasicDeliverEventArgs requestPayload)
 		{
-			return Task.Run(() =>
+			return new BasicProperties
 			{
-				IBasicProperties replyProps = new BasicProperties
-				{
-					CorrelationId = requestPayload.BasicProperties.CorrelationId
-				};
-				return replyProps;
-			});
+				CorrelationId = requestPayload.BasicProperties.CorrelationId
+			};
 		}

 		public override void Dispose()


CMIS-503: removed typeId parameter

CMIS-503: removed typeId parameter

git-svn-id: 024815966b14bc162104d7308994938bf1039524@1243244 13f79535-47bb-0310-9956-ffa450edef68

--- DotCMIS/binding/atompub/atompub.cs
+++ DotCMIS/binding/atompub/atompub.cs
@@ -859,7 +859,6 @@
             }

             UrlBuilder url = new UrlBuilder(link);
-            url.AddParameter(AtomPubConstants.ParamTypeId, typeId);
             url.AddParameter(AtomPubConstants.ParamPropertyDefinitions, includePropertyDefinitions);
             url.AddParameter(AtomPubConstants.ParamMaxItems, maxItems);
             url.AddParameter(AtomPubConstants.ParamSkipCount, skipCount);
@@ -939,7 +938,6 @@
             }

             UrlBuilder url = new UrlBuilder(link);
-            url.AddParameter(AtomPubConstants.ParamTypeId, typeId);
             url.AddParameter(AtomPubConstants.ParamDepth, depth);
             url.AddParameter(AtomPubConstants.ParamPropertyDefinitions, includePropertyDefinitions);


Compatibility with 1.3.x

Compatibility with 1.3.x

--- Duplicati/Server/SingleInstance.cs
+++ Duplicati/Server/SingleInstance.cs
@@ -67,15 +67,15 @@
         /// <summary>
         /// The folder where control files are placed
         /// </summary>
-        private const string CONTROL_DIR = "control_dir";
+        private const string CONTROL_DIR = "control_dir_v2";
         /// <summary>
         /// The file that is locked by the first process
         /// </summary>
-        private const string CONTROL_FILE = "lock";
+        private const string CONTROL_FILE = "lock_v2";
         /// <summary>
         /// The prefix on files that communicate with the first instance
         /// </summary>
-        private const string COMM_FILE_PREFIX = "other_invocation_";
+        private const string COMM_FILE_PREFIX = "other_invocation_v2_";

         /// <summary>
         /// The delegate that is used to inform the first instance of the second invocation


Use Log.Logger in sample to allow flush

Use Log.Logger in sample to allow flush

--- examples/Serilog.Sinks.ElmahIo.Example/Program.cs
+++ examples/Serilog.Sinks.ElmahIo.Example/Program.cs
@@ -21,7 +21,7 @@
     {
         static void Main(string[] args)
         {
-            var logger =
+            Log.Logger =
                 new LoggerConfiguration()
                     .Enrich.WithProperty("Hello", "World")
                     .Enrich.FromLogContext()
@@ -34,7 +34,7 @@

             using (LogContext.PushProperty("LogContext property", "with some value"))
             {
-                logger.Error("This is a log message with a {TypeOfProperty} message", "structured");
+                Log.Error("This is a log message with a {TypeOfProperty} message", "structured");
             }

             try
@@ -44,15 +44,15 @@
             }
             catch (Exception e)
             {
-                logger.Error(e, "Some exception");
+                Log.Error(e, "Some exception");
             }

-            logger.Information("A message with {type} {hostname} {application} {user} {source} {method} {version} {url} and {statusCode}",
+            Log.Information("A message with {type} {hostname} {application} {user} {source} {method} {version} {url} and {statusCode}",
                 "custom type", "custom hostname", "custom application", "custom user", "custom source", "custom method",
                 "custom version", "custom url", 500);

-            Console.WriteLine("Wait 5 seconds and press any key to exit.");
-            Console.ReadKey();
+            // Make sure to emit any batched messages not already sent to elmah.io.
+            Log.CloseAndFlush();
         }
     }
 }


autostart

autostart

--- MasDev.Common/MasDev.Common.Data.NHibernate/Source/NHibernateBaseRepository.cs
+++ MasDev.Common/MasDev.Common.Data.NHibernate/Source/NHibernateBaseRepository.cs
@@ -243,7 +243,7 @@
 		public virtual void CommitWork ()
 		{
 			if (IsInTransaction)
-				_uow.Commit ();
+				_uow.Commit (true);
 			else
 				throw new Exception ("Work not has not started");
 		}
@@ -253,7 +253,7 @@
 		public virtual void RollbackWork ()
 		{
 			if (IsInTransaction)
-				_uow.Rollback ();
+				_uow.Rollback (true);
 			else
 				throw new Exception ("Work not has not started");
 		}


file result cache

file result cache

--- MasDev.Common/Rest/MasDev.Common.Rest.WebApi/Source/WebApi/Utils/FileResult.cs
+++ MasDev.Common/Rest/MasDev.Common.Rest.WebApi/Source/WebApi/Utils/FileResult.cs
@@ -7,19 +7,25 @@
 using System.IO;
 using System.Web;
 using System.Net.Http.Headers;
-using MasDev.IO.Http;
-using MasDev.Extensions;
 using MasDev.Common;
+using System.Collections.Generic;
+using System.Linq;
+using MasDev.Utils;
+using System.Text;
+using System.Diagnostics;

 namespace MasDev.Rest.WebApi
 {
 	public class FileResult : IHttpActionResult
 	{
+		public static readonly FileCache Cache = new FileCache ();
+
 		readonly string _filePath;
 		readonly string _contentType;
 		readonly HttpStatusCode _statusCode;
 		readonly DateTime? _ifModifiedSince;
+		readonly bool _useCache;

 		public FileResult (IfModifiedSinceHeader ifModifiedSince, string filePath, string contentType = null)
 		{
@@ -32,28 +38,75 @@
 			_ifModifiedSince = ifModifiedSince == null ? null : (DateTime?)ifModifiedSince.TimeUtc;
 		}

+		public FileResult (IfModifiedSinceHeader ifModifiedSince, string filePath, bool useCache, string contentType = null) : this (ifModifiedSince, filePath, contentType)
+		{
+			_useCache = useCache;
+		}
+
 		public FileResult (IfModifiedSinceHeader ifModifiedSince, string filePath, HttpStatusCode statusCode, string contentType = null) : this (ifModifiedSince, filePath, contentType)
 		{
 			_statusCode = statusCode;
 		}

-		public Task<HttpResponseMessage> ExecuteAsync (CancellationToken cancellationToken)
-		{
-			var fileInfo = new FileInfo (_filePath);
+		public FileResult (IfModifiedSinceHeader ifModifiedSince, string filePath, HttpStatusCode statusCode, bool useCache, string contentType = null) : this (ifModifiedSince, filePath, statusCode, contentType)
+		{
+			_useCache = useCache;
+		}
+
+		public async Task<HttpResponseMessage> ExecuteAsync (CancellationToken cancellationToken)
+		{
+			FileCache.CachedFile cachedFile = null;
+			FileInfo fileInfo = null;
+			DateTime lastModifiedUtc;
+
+			if (_useCache && Cache.Has (_filePath)) {
+				cachedFile = Cache [_filePath];
+				lastModifiedUtc = cachedFile.LastModifiedUtc;
+			} else {
+				fileInfo = new FileInfo (_filePath);
+				lastModifiedUtc = fileInfo.LastWriteTimeUtc;
+			}
+
 			if (_ifModifiedSince.HasValue && _statusCode == HttpStatusCode.OK) {
-				if (fileInfo.LastWriteTimeUtc <= _ifModifiedSince.Value)
-					return Task.FromResult (new HttpResponseMessage (HttpStatusCode.NotModified));
+				if (lastModifiedUtc <= _ifModifiedSince.Value)
+					return new HttpResponseMessage (HttpStatusCode.NotModified);
 			}

-			var response = new HttpResponseMessage (HttpStatusCode.OK) {
-				Content = new StreamContent (File.OpenRead (_filePath))
-			};
+			var response = new HttpResponseMessage (HttpStatusCode.OK);
+			if (!_useCache) {
+				response.Content = new StreamContent (File.OpenRead (_filePath));
+			} else {
+				string stringContent;
+
+				if (cachedFile == null) {
+					using (var fileStream = new FileStream (_filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true)) {
+						var sb = new StringBuilder ();
+						var buffer = new byte[0x1000];
+						int numRead;
+						while ((numRead = await fileStream.ReadAsync (buffer, 0, buffer.Length)) != 0) {
+							cancellationToken.ThrowIfCancellationRequested ();
+							var text = Encoding.Unicode.GetString (buffer, 0, numRead);
+							sb.Append (text);
+						}
+						stringContent = sb.ToString ();
+					}
+					Cache [_filePath] = new FileCache.CachedFile {
+						Content = stringContent,
+						LastModifiedUtc = fileInfo.LastWriteTimeUtc,
+						Length = fileInfo.Length
+					};
+				} else {
+					stringContent = cachedFile.Content;
+				}
+
+				response.Content = new StringContent (stringContent, Encoding.Unicode);
+			}

-			response.Content.Headers.LastModified = fileInfo.LastWriteTimeUtc;
+			response.Content.Headers.LastModified = lastModifiedUtc;
 			var contentType = _contentType ?? MimeMapping.GetMimeMapping (Path.GetExtension (_filePath));
 			response.Content.Headers.ContentType = new MediaTypeHeaderValue (contentType);

-			return Task.FromResult (response);
+			return response;
 		}

@@ -63,5 +116,111 @@
 			return result.ExecuteAsync (CancellationToken.None);
 		}
 	}
+
+
+	public class FileCache
+	{
+		public class CachedFile
+		{
+			public DateTime LastModifiedUtc { get; set; }
+
+			public string Content { get; set; }
+
+			public long Length { get; set; }
+		}
+
+		long _currentSize;
+		Queue<string> _lru;
+		readonly Dictionary<string, CachedFile> _cache;
+		readonly object _lock;
+
+		/// <summary>
+		/// Gets or sets the maximum size of the cache (in bytes)
+		/// </summary>
+		/// <value>The max size.</value>
+		public long MaxSize { get; set; }
+
+		/// <summary>
+		/// Gets the current size in bytes of the cache.
+		/// </summary>
+		/// <value>The current size</value>
+		public double CurrentSize { get { return _currentSize; } }
+
+		public FileCache ()
+		{
+			_cache = new Dictionary<string, CachedFile> ();
+			_lru = new Queue<string> ();
+			_currentSize = 0;
+			_lock = new object ();
+			MaxSize = long.MaxValue;
+		}
+
+		public FileCache (long maxSize) : this ()
+		{
+			MaxSize = maxSize;
+		}
+
+		public bool Has (string path)
+		{
+			return this [path] != null;
+		}
+
+
+		public CachedFile this [string path] {
+			get {
+				lock (_lock) {
+					return _cache.ContainsKey (path) ? _cache [path] : null;
+				}
+			}
+
+			set {
+				lock (_lock) {
+					Assert.NotNull (value);
+
+					while (MaxSize < (_currentSize + value.Length)) {
+						if (!_lru.Any ())
+							throw new ArgumentException ("File too big for this cache. Maximum allowed: " + MaxSize + ", but got " + value.Length);
+
+
+						var lruPath = _lru.Dequeue ();
+						var lruFile = _cache [lruPath];
+						_cache.Remove (lruPath);
+						_currentSize -= lruFile.Length;
+					}
+
+					_currentSize += value.Length;
+					_cache [path] = value;
+					_lru.Enqueue (path);
+				}
+			}
+		}
+
+		public void Invalidate ()
+		{
+			lock (_lock) {
+				_cache.Clear ();
+			}
+		}
+
+		public void Invalidate (string path)
+		{
+			lock (_lock) {
+				if (!_cache.ContainsKey (path))
+					return;
+
+				var file = _cache [path];
+				_currentSize -= file.Length;
+
+				var newLru = new Queue<string> ();
+				while (_lru.Any ()) {
+					var queueHead = _lru.Dequeue ();
+					if (queueHead == path)
+						continue;
+					newLru.Enqueue (path);
+				}
+				_lru = newLru;
+			}
+		}
+	}
 }


Improvements

Improvements

- Replace bitwise And operation for .HasFlag call
- Minor change in object store permission error message

--- Engine/Storage/LocalObjectStore.cs
+++ Engine/Storage/LocalObjectStore.cs
@@ -39,13 +39,13 @@
         /// No read permissions error message
         /// </summary>
         protected const string NoReadPermissionsError = "The current user does not have permission to read from the organization Object Store." +
-                                                        " Please contact your organization administrator for more information.";
+                                                        " Please contact your organization administrator to request permission.";

         /// <summary>
         /// No write permissions error message
         /// </summary>
         protected const string NoWritePermissionsError = "The current user does not have permission to write to the organization Object Store." +
-                                                         " Please contact your organization administrator for more information.";
+                                                         " Please contact your organization administrator to request permission.";

         /// <summary>
         /// Event raised each time there's an error
@@ -89,7 +89,9 @@

             Log.Trace($"LocalObjectStore.Initialize(): Storage Root: {new FileInfo(AlgorithmStorageRoot).FullName}");

-            if ((controls.StoragePermissions & FileAccess.Read) == FileAccess.Read)
+            Controls = controls;
+
+            if (Controls.StoragePermissions.HasFlag(FileAccess.Read))
             {
                 foreach (var file in Directory.EnumerateFiles(AlgorithmStorageRoot))
                 {
@@ -98,12 +100,10 @@
                 }
             }

-            Controls = controls;
-
             // if <= 0 we disable periodic persistence and make it synchronous
-            if (controls.PersistenceIntervalSeconds > 0)
-            {
-                _persistenceInterval = TimeSpan.FromSeconds(controls.PersistenceIntervalSeconds);
+            if (Controls.PersistenceIntervalSeconds > 0)
+            {
+                _persistenceInterval = TimeSpan.FromSeconds(Controls.PersistenceIntervalSeconds);
                 _persistenceTimer = new Timer(_ => Persist(), null, _persistenceInterval, _persistenceInterval);
             }
         }
@@ -119,7 +119,7 @@
             {
                 throw new ArgumentNullException(nameof(key));
             }
-            if ((Controls.StoragePermissions & FileAccess.Read) == 0)
+            if (!Controls.StoragePermissions.HasFlag(FileAccess.Read))
             {
                 throw new InvalidOperationException($"LocalObjectStore.ContainsKey(): {NoReadPermissionsError}");
             }
@@ -138,7 +138,7 @@
             {
                 throw new ArgumentNullException(nameof(key));
             }
-            if ((Controls.StoragePermissions & FileAccess.Read) == 0)
+            if (!Controls.StoragePermissions.HasFlag(FileAccess.Read))
             {
                 throw new InvalidOperationException($"LocalObjectStore.ReadBytes(): {NoReadPermissionsError}");
             }
@@ -166,7 +166,7 @@
             {
                 throw new ArgumentNullException(nameof(key));
             }
-            if ((Controls.StoragePermissions & FileAccess.Write) == 0)
+            if (!Controls.StoragePermissions.HasFlag(FileAccess.Write))
             {
                 throw new InvalidOperationException($"LocalObjectStore.SaveBytes(): {NoWritePermissionsError}");
             }
@@ -239,7 +239,7 @@
             {
                 throw new ArgumentNullException(nameof(key));
             }
-            if ((Controls.StoragePermissions & FileAccess.Write) == 0)
+            if (!Controls.StoragePermissions.HasFlag(FileAccess.Write))
             {
                 throw new InvalidOperationException($"LocalObjectStore.Delete(): {NoWritePermissionsError}");
             }


Use smaller epub for saving test, so that online validators accept the size.

--- EpubSharp.Tests/EpubWriterTests.cs
+++ EpubSharp.Tests/EpubWriterTests.cs
@@ -13,7 +13,7 @@
         [TestMethod]
         public void SaveTest()
         {
-            var book = EpubReader.Read(@"../../Samples/epub-assorted/iOS Hackers Handbook.epub");
+            var book = EpubReader.Read(@"../../Samples/epub-assorted/Inversions - Iain M. Banks.epub");
             var writer = new EpubWriter(book);
             writer.Save("saved.epub");
         }