Fixed bugs in tests

Fixed bugs in tests

--- src/Redwood.Framework.Tests/Runtime/DefaultViewCompilerTests.cs
+++ src/Redwood.Framework.Tests/Runtime/DefaultViewCompilerTests.cs
@@ -157,10 +157,10 @@
         [TestMethod]
         public void DefaultViewCompiler_CodeGeneration_MarkupControlWithBaseType()
         {
-            var markup = @"<cc:Test1 />";
-            var page = CompileMarkup(markup, new Dictionary<string, string>()
-            {
-                { "test1.rwhtml", string.Format("@baseType {0}, {1}\r\n<rw:Literal Text='aaa' />", typeof(TestControl), typeof(TestControl).Assembly.GetName().Name) }
+            var markup = @"<cc:Test2 />";
+            var page = CompileMarkup(markup, new Dictionary<string, string>()
+            {
+                { "test2.rwhtml", string.Format("@baseType {0}, {1}\r\n<rw:Literal Text='aaa' />", typeof(TestControl), typeof(TestControl).Assembly.GetName().Name) }
             });

             Assert.IsInstanceOfType(page, typeof(RedwoodView));
@@ -176,12 +176,12 @@
         {
             var markup = @"<rw:Repeater>
     <ItemTemplate>
-        <cc:Test1 />
+        <cc:Test3 />
     </ItemTemplate>
 </rw:Repeater>";
             var page = CompileMarkup(markup, new Dictionary<string, string>()
             {
-                { "test1.rwhtml", "<rw:Literal Text='aaa' />" }
+                { "test3.rwhtml", "<rw:Literal Text='aaa' />" }
             });

             Assert.IsInstanceOfType(page, typeof(RedwoodView));
@@ -210,12 +210,12 @@
         {
             var markup = @"<rw:Repeater>
     <ItemTemplate>
-        <cc:Test1 />
+        <cc:Test4 />
     </ItemTemplate>
 </rw:Repeater>";
             var page = CompileMarkup(markup, new Dictionary<string, string>()
             {
-                { "test1.rwhtml", "<rw:Literal Text='aaa' />" }
+                { "test4.rwhtml", "<rw:Literal Text='aaa' />" }
             }, compileTwice: true);

             Assert.IsInstanceOfType(page, typeof(RedwoodView));
@@ -244,12 +244,10 @@
         private static RedwoodControl CompileMarkup(string markup, Dictionary<string, string> markupFiles = null, bool compileTwice = false)
         {
             var redwoodConfiguration = RedwoodConfiguration.CreateDefault();
-            redwoodConfiguration.Markup.Controls.Add(new RedwoodControlConfiguration()
-            {
-                TagPrefix = "cc",
-                TagName = "Test1",
-                Src = "test1.rwhtml"
-            });
+            redwoodConfiguration.Markup.Controls.Add(new RedwoodControlConfiguration() { TagPrefix = "cc", TagName = "Test1", Src = "test1.rwhtml" });
+            redwoodConfiguration.Markup.Controls.Add(new RedwoodControlConfiguration() { TagPrefix = "cc", TagName = "Test2", Src = "test2.rwhtml" });
+            redwoodConfiguration.Markup.Controls.Add(new RedwoodControlConfiguration() { TagPrefix = "cc", TagName = "Test3", Src = "test3.rwhtml" });
+            redwoodConfiguration.Markup.Controls.Add(new RedwoodControlConfiguration() { TagPrefix = "cc", TagName = "Test4", Src = "test4.rwhtml" });
             redwoodConfiguration.ServiceLocator.RegisterSingleton<IMarkupFileLoader>(() => new FakeMarkupFileLoader(markupFiles));
             redwoodConfiguration.Markup.AddAssembly(Assembly.GetExecutingAssembly().GetName().Name);
             var compiler = redwoodConfiguration.ServiceLocator.GetService<IViewCompiler>();


Observe .Load cancellation request

Observe .Load cancellation request

--- DataConverters3D/Object3D/Object3DExtensions.cs
+++ DataConverters3D/Object3D/Object3DExtensions.cs
@@ -69,6 +69,9 @@

 		private static void LoadLinkedMesh(this IObject3D item, Dictionary<string, IObject3D> itemCache, CancellationToken cancellationToken, Action<double, string> progress)
 		{
+			// Abort load if cancel requested
+			cancellationToken.ThrowIfCancellationRequested();
+
 			// Natural path
 			string filePath = item.MeshPath;

@@ -92,11 +95,6 @@

 			var loadedItem = Object3D.Load(filePath, cancellationToken, itemCache, progress);

-			// TODO: Consider refactoring progress reporting to use an instance with state and the original delegate reference to allow anyone along the chain
-			// to determine if continueProcessing has been set to false and allow for more clear aborting (rather than checking for null as we have to do below)
-			//
-			// During startup we reload the main control multiple times. When the timing is right, reportProgress0to100 may set continueProcessing
-			// on the reporter to false and MeshFileIo.Load will return null. In those cases, we need to exit rather than continue processing
 			if (loadedItem != null)
 			{
 				item.SetMeshDirect(loadedItem.Mesh);


New clientlib ver

New clientlib ver

--- KalturaClient/KalturaClient.cs
+++ KalturaClient/KalturaClient.cs
@@ -34,7 +34,7 @@
 		public KalturaClient(KalturaConfiguration config) : base(config)
 		{
 				ApiVersion = "3.3.0";
-				ClientTag = "dotnet:16-04-23";
+				ClientTag = "dotnet:16-04-24";
 		}

 		KalturaAccessControlProfileService _AccessControlProfileService;


Follow naming guidelines

Follow naming guidelines

- Avoid var when type is not apparent on right side of assignment

--- DataConverters3D/Object3D/Object3DExtensions.cs
+++ DataConverters3D/Object3D/Object3DExtensions.cs
@@ -244,7 +244,7 @@
 					}

 					// Calculate the fast mesh hash
-					var hashCode = item.Mesh.GetLongHashCode();
+					long hashCode = item.Mesh.GetLongHashCode();

 					// Index into dictionary using fast hash
 					if (!assetFiles.TryGetValue(hashCode, out string assetPath))


New clientlib ver

New clientlib ver

--- KalturaClient/KalturaClient.cs
+++ KalturaClient/KalturaClient.cs
@@ -34,7 +34,7 @@
 		public KalturaClient(KalturaConfiguration config) : base(config)
 		{
 				ApiVersion = "3.3.0";
-				ClientTag = "dotnet:15-09-27";
+				ClientTag = "dotnet:15-09-28";
 		}

 		KalturaAccessControlProfileService _AccessControlProfileService;


tracks commit 6ea48d624c8122c5dd1d22f6feef83e4f9c86695 no changes required

--- DiffMatchPatch.Tests/DiffMatchPatch.Original.cs
+++ DiffMatchPatch.Tests/DiffMatchPatch.Original.cs
@@ -383,10 +383,10 @@
     private List<Diff> diff_lineMode(string text1, string text2,
                                      DateTime deadline) {
       // Scan the text on a line-by-line basis first.
-      Object[] b = diff_linesToChars(text1, text2);
-      text1 = (string)b[0];
-      text2 = (string)b[1];
-      List<string> linearray = (List<string>)b[2];
+      Object[] a = diff_linesToChars(text1, text2);
+      text1 = (string)a[0];
+      text2 = (string)a[1];
+      List<string> linearray = (List<string>)a[2];

       List<Diff> diffs = diff_main(text1, text2, false, deadline);

@@ -420,10 +420,10 @@
               diffs.RemoveRange(pointer - count_delete - count_insert,
                   count_delete + count_insert);
               pointer = pointer - count_delete - count_insert;
-              List<Diff> a =
+              List<Diff> subDiff =
                   this.diff_main(text_delete, text_insert, false, deadline);
-              diffs.InsertRange(pointer, a);
-              pointer = pointer + a.Count;
+              diffs.InsertRange(pointer, subDiff);
+              pointer = pointer + subDiff.Count;
             }
             count_insert = 0;
             count_delete = 0;


Fixed missing SightingId

Fixed missing SightingId

--- Kustobsar.Ap2.Data/ParseData/Storage/ParseSightingsStorage.cs
+++ Kustobsar.Ap2.Data/ParseData/Storage/ParseSightingsStorage.cs
@@ -31,6 +31,7 @@
             var parseSighting = new ParseSighting
             {
                 ObjectId = sighting.ParseId,
+                SightingId = sighting.SightingId,
                 TaxonPrefix = sighting.Taxon.Prefix,
                 TaxonId = sighting.Taxon.TaxonId,
                 TaxonName = sighting.Taxon.CommonName,


Dispose the mobile API properly

Dispose the mobile API properly

--- Espera/Espera.View/ViewModels/ShellViewModel.cs
+++ Espera/Espera.View/ViewModels/ShellViewModel.cs
@@ -439,6 +439,11 @@
             this.library.Dispose();

             this.disposable.Dispose();
+
+            if(this.mobileApi != null)
+            {
+                this.mobileApi.Dispose();
+            }
         }

         private void AddPlaylist()


[Metrics] Add MountRemote events to Metrics.Shared

GitOrigin-RevId: f84afdf349aa971204c41f94117fa575777c0665

--- Metrics.Shared/DeveloperEventType.cs
+++ Metrics.Shared/DeveloperEventType.cs
@@ -59,7 +59,14 @@
                 VsiGameLaunchGetExisting,
                 VsiDebugExpressionEvaluationBatch,
                 VsiReportFeedback,
-                VsiShutdown
+                VsiShutdown,
+                MrAddHost,
+                MrException,
+                MrListHosts,
+                MrProcessStart,
+                MrReconnect,
+                MrRemoveHost,
+                MrUpdateAllHosts
             }
         }
     }


Use the built-in GridLength class instead of our own "conversion" for saving the playlist height

--- Espera/Espera.View/ViewModels/ShellViewModel.cs
+++ Espera/Espera.View/ViewModels/ShellViewModel.cs
@@ -9,6 +9,7 @@
 using System.Collections.ObjectModel;
 using System.Linq;
 using System.Timers;
+using System.Windows;
 using System.Windows.Input;

 namespace Espera.View.ViewModels
@@ -371,13 +372,13 @@
         }

         // Save the playlist height as string, so that the initial value can be "*"
-        public string PlaylistHeight
-        {
-            get { return Settings.Default.PlaylistHeight; }
+        public GridLength PlaylistHeight
+        {
+            get { return (GridLength)new GridLengthConverter().ConvertFrom(Settings.Default.PlaylistHeight); }
             set
             {
                 // Remove the "*" from value, as it causes the playlist to fill all the space
-                Settings.Default.PlaylistHeight = value.Remove(value.Length - 1);
+                Settings.Default.PlaylistHeight = (string)new GridLengthConverter().ConvertTo(value, typeof(string));
             }
         }


Elbtunnel: Minor bugs removed

Elbtunnel: Minor bugs removed

--- Models/Elbtunnel/Vehicles/Vehicle.cs
+++ Models/Elbtunnel/Vehicles/Vehicle.cs
@@ -86,7 +86,7 @@
 		/// </summary>
 		void IInitializable.Initialize()
 		{
-			Lane = Choose(Lane.Left, Lane.Right);
+			Lane = Lane.Right;
 			Speed = ChooseFromRange(0, Specification.MaxSpeed);
 		}

@@ -94,7 +94,7 @@
 		{
 			// The road layout makes lane changes impossible when the end control has been reached
 			if (Position < Specification.EndControlPosition)
-				Lane = Choose(Lane.Right);
+				Lane = Lane.Right;
 		}

 		/// <summary>


Fix analytics fields names

Fix analytics fields names

--- Kudu.Core/Tracing/Analytics.cs
+++ Kudu.Core/Tracing/Analytics.cs
@@ -32,9 +32,9 @@
         public void JobStarted(string jobName, string scriptExtension, string jobType, string siteMode, string error)
         {
             var o = new KuduSiteExtensionLogEvent("JobStarted");
-            o["WebJobsName"] = jobName;
+            o["JobName"] = jobName;
             o["ScriptExtension"] = scriptExtension;
-            o["WebJobsType"] = jobType;
+            o["JobType"] = jobType;
             o["SiteMode"] = siteMode;
             o["Error"] = error;


Code cleanup.

Code cleanup.

--- LazerTagHostLibrary/HostGun.cs
+++ LazerTagHostLibrary/HostGun.cs
@@ -18,8 +18,7 @@
     {
         static private void HostDebugWriteLine(string line)
         {
-            DateTime now = DateTime.Now;
-            Console.WriteLine("Host: (" + now + ") " + line);
+            Console.WriteLine("{0}: {1}", DateTime.Now, line);
         }

         private struct GameState {
@@ -694,17 +693,16 @@
             case HostingState.HOSTING_STATE_SUMMARY:
             {
                 IRPacket command_packet = incoming_packet_queue[0];
-                switch ((CommandCode)command_packet.data) {
-                case CommandCode.COMMAND_CODE_PLAYER_REPORT_SCORE:
-                    return ProcessPlayerReportScore();
-                case CommandCode.COMMAND_CODE_PLAYER_HIT_BY_TEAM_1_REPORT:
-                case CommandCode.COMMAND_CODE_PLAYER_HIT_BY_TEAM_2_REPORT:
-                case CommandCode.COMMAND_CODE_PLAYER_HIT_BY_TEAM_3_REPORT:
-                    return ProcessPlayerHitByTeamReport();
-                default:
-                    break;
-                }
-
+                switch ((CommandCode)command_packet.data)
+				{
+					case CommandCode.COMMAND_CODE_PLAYER_REPORT_SCORE:
+						return ProcessPlayerReportScore();
+					case CommandCode.COMMAND_CODE_PLAYER_HIT_BY_TEAM_1_REPORT:
+					case CommandCode.COMMAND_CODE_PLAYER_HIT_BY_TEAM_2_REPORT:
+					case CommandCode.COMMAND_CODE_PLAYER_HIT_BY_TEAM_3_REPORT:
+		                return ProcessPlayerHitByTeamReport();
+                }
+
                 return false;
             }
             default:
@@ -1244,29 +1242,22 @@
             string countdown;

             if (state_change_timeout < now || paused) {
-
-                countdown = "Waiting";
-
-                switch (hosting_state) {
-                case HostingState.HOSTING_STATE_ADDING:
-                    int needed = (MINIMUM_PLAYER_COUNT_START - players.Count);
-                    if (needed > 0) {
-                        countdown = "Waiting for " + needed + " more players";
-                    } else {
-                        countdown = "Ready to start";
-                    }
-                    break;
-                case HostingState.HOSTING_STATE_SUMMARY:
-                    countdown += " for all players to check in";
-                    break;
-                case HostingState.HOSTING_STATE_GAME_OVER:
-                    countdown = "All players may now receive scores";
-                    break;
-                default:
-                    break;
-                }
-
-
+                switch (hosting_state)
+				{
+					case HostingState.HOSTING_STATE_ADDING:
+						int needed = (MINIMUM_PLAYER_COUNT_START - players.Count);
+						countdown = needed > 0 ? String.Format("Waiting for {0} more players", needed) : "Ready to start";
+						break;
+					case HostingState.HOSTING_STATE_SUMMARY:
+						countdown = "Waiting for all players to check in";
+						break;
+					case HostingState.HOSTING_STATE_GAME_OVER:
+						countdown = "All players may now receive scores";
+						break;
+					default:
+						countdown = "Waiting";
+		                break;
+                }
             } else {
                 countdown = ((int)((state_change_timeout - now).TotalSeconds)).ToString() + " seconds";

@@ -1536,39 +1527,12 @@
 		                next_announce = now.AddMilliseconds(1000);
 	                }
                 }
-#region TestData
-                //TODO: Won't get called if next announce is not advanced
-				try
+                break;
+            }
+            case HostingState.HOSTING_STATE_SUMMARY:
+            {
+                if (now > next_announce)
 				{
-					if (Console.KeyAvailable)
-					{
-						char input = (char)Console.Read();
-
-						if (input >= '0' && input <= '7')
-						{
-							int player_number = input - '0';
-
-							int damage = 0;
-							Shoot(host_shot_team_number, player_number, damage, true);
-						}
-						else
-						{
-							host_shot_team_number = (host_shot_team_number % 3) + 1;
-							HostDebugWriteLine("Host gun set to shoot for team: " + host_shot_team_number);
-						}
-					}
-				}
-				catch (InvalidOperationException)
-				{
-					// Console input not available. Ignore.
-				}
-#endregion
-                break;
-            }
-            case HostingState.HOSTING_STATE_SUMMARY:
-            {
-                if (now > next_announce) {
-
                     Player next_debrief = null;

                     //pull players off the debrief list at random
@@ -1585,8 +1549,9 @@
                         }
                     }

-                    if (next_debrief == null) {
-                        HostDebugWriteLine("All players briefed");
+                    if (next_debrief == null)
+					{
+                        HostDebugWriteLine("All players debriefed");

                         RankPlayers();
                         PrintScoreReport();
@@ -1595,38 +1560,38 @@
                         break;
                     }

-                    UInt16 player_index = (UInt16)((next_debrief.team_number & 0xf) << 4 | (next_debrief.player_number & 0xf));
-
-                    next_announce = now.AddSeconds(GAME_DEBRIEF_ADVERTISEMENT_INTERVAL_SECONDS);
-                    UInt16[] values = new UInt16[]{
+                    var player_index = (UInt16)((next_debrief.team_number & 0xf) << 4 | (next_debrief.player_number & 0xf));
+                    var values = new UInt16[]
+					{
                         (UInt16)CommandCode.COMMAND_CODE_SCORE_ANNOUNCEMENT,
-                        game_id,//Game ID
-                        player_index,//player index
-                        // [ 4 bits - team ] [ 4 bits - player number ]
-                        0x0F, //unknown
+                        game_id, // Game ID
+                        player_index, // player index [ 4 bits - team ] [ 4 bits - player number ]
+                        0x0F, // unknown
                     };
                     TransmitPacket2(ref values);
-                }
+
+					next_announce = now.AddSeconds(GAME_DEBRIEF_ADVERTISEMENT_INTERVAL_SECONDS);
+				}
                 break;
             }
             case HostingState.HOSTING_STATE_GAME_OVER:
             {
-                if (now > next_announce) {
-
+                if (now > next_announce)
+				{
                     next_announce = now.AddSeconds(GAME_OVER_ADVERTISEMENT_INTERVAL_SECONDS);

-                    foreach (Player p in players) {
-
+                    foreach (Player p in players)
+					{
                         UInt16 player_index = (UInt16)((p.team_number & 0xf) << 4 | (p.player_number & 0xf));

-                        UInt16[] values = new UInt16[]{
+                        UInt16[] values = new UInt16[]
+						{
                             (UInt16)CommandCode.COMMAND_CODE_GAME_OVER,
-                            game_id,//Game ID
-                            player_index,//player index
-                            // [ 4 bits - team ] [ 4 bits - player number ]
-                            (UInt16)p.individual_rank, //player rank (not decimal hex, 1-player_count)
-                            (UInt16)p.team_rank, //team rank?
-                            0x00,//unknown...
+                            game_id, // Game ID
+                            player_index, // player index [ 4 bits - team ] [ 4 bits - player number ]
+                            (UInt16)p.individual_rank, // player rank (not decimal hex, 1-player_count)
+                            (UInt16)p.team_rank, // team rank?
+                            0x00, // unknown...
                             0x00,
                             0x00,
                             0x00,
@@ -1634,15 +1599,11 @@
                         };
                         TransmitPacket2(ref values);
                     }
-
-                }
-                break;
-            }
-            default:
-                break;
-            }
-        }
-
+                }
+                break;
+            }
+            }
+        }

         public void AddListener(HostChangedListener listener) {
             this.listener = listener;


Added a meaningful exception message for ExcelTableColumn casting errors

--- src/EPPlus.Core.Extensions/ExcelTableExtensions.cs
+++ src/EPPlus.Core.Extensions/ExcelTableExtensions.cs
@@ -63,13 +63,13 @@
                     catch
                     {
                         result.AddLast(new ExcelTableConvertExceptionArgs
-                        {
-                            ColumnName = table.Columns[map.Key].Name,
-                            ExpectedType = property.PropertyType,
-                            PropertyName = property.Name,
-                            CellValue = cell,
-                            CellAddress = new ExcelCellAddress(row, map.Key + table.Address.Start.Column)
-                        });
+                                       {
+                                           ColumnName = table.Columns[map.Key].Name,
+                                           ExpectedType = property.PropertyType,
+                                           PropertyName = property.Name,
+                                           CellValue = cell,
+                                           CellAddress = new ExcelCellAddress(row, map.Key + table.Address.Start.Column)
+                                       });
                     }
                 }
             }
@@ -124,16 +124,17 @@
                     {
                         if (!skipCastErrors)
                         {
-                            throw new ExcelTableConvertException("An error occured while parsing the cell",
-                                ex,
-                                new ExcelTableConvertExceptionArgs
-                                {
-                                    ColumnName = table.Columns[map.Key].Name,
-                                    ExpectedType = property.PropertyType,
-                                    PropertyName = property.Name,
-                                    CellValue = cell,
-                                    CellAddress = new ExcelCellAddress(row, map.Key + table.Address.Start.Column)
-                                }
+                            var exceptionArgs = new ExcelTableConvertExceptionArgs
+                                                {
+                                                    ColumnName = table.Columns[map.Key].Name,
+                                                    ExpectedType = property.PropertyType,
+                                                    PropertyName = property.Name,
+                                                    CellValue = cell,
+                                                    CellAddress = new ExcelCellAddress(row, map.Key + table.Address.Start.Column)
+                                                };
+
+                            throw new ExcelTableConvertException($"The expected type of '{exceptionArgs.PropertyName}' property is '{exceptionArgs.ExpectedType.Name}', but the cell [{exceptionArgs.CellAddress.Address}] contains an invalid value.",
+                                ex, exceptionArgs
                             );
                         }
                     }


Fixed integration tests for ColumnTypeConverter

--- src/Testing/ADatabaseTest/IntegrationTestColumnTypeConverter.cs
+++ src/Testing/ADatabaseTest/IntegrationTestColumnTypeConverter.cs
@@ -11,6 +11,10 @@
     [TestClass]
     public class IntegrationTestColumnTypeConverter
     {
+        private int _length;
+        private int _prec;
+        private int _scale;
+
         private readonly IColumnTypeConverter _columnTypeConverter =
             new ColumnTypeConverter(
                 new XmlConversionsReader(
@@ -18,145 +22,164 @@
                         new TypeConstraintFactory(
                             new TypeOperatorFactory()))));

-        private string GetDestinationType(string input, int length, int prec, int scale)
+        private string GetDestinationType(string input, ref int length, ref int prec, ref int scale)
         {
-            var newLength = length;
-            var newPrec = prec;
-            var newScale = scale;
-
-            return _columnTypeConverter.GetDestinationType("illegal_type(@Length)", ref length, ref prec, ref scale);
+            return _columnTypeConverter.GetDestinationType(input, ref length, ref prec, ref scale);
         }

         [TestInitialize]
         public void Startup()
         {
+            _length = 0;
+            _prec = 0;
+            _scale = 0;
             _columnTypeConverter.Initialize(ConversionXmlHelper.Unit4OracleConversionsXml());
         }

         [TestMethod]
         public void TestGetDestinationType_When_IllegalTypeName()
         {
-            Action act = () => GetDestinationType("illegal_type(@Length)", 25, 0, 0);
+            _length = 25;
+            Action act = () => GetDestinationType("illegal_type(@Length)", ref _length, ref _prec, ref _scale);
             act.ShouldThrow<AColumnTypeException>()
-                .WithMessage("Illegal type: 'illegal_type(@Length)', length=25, prec=, scale=");
+                .WithMessage("Illegal type: 'illegal_type(@Length)', length=25, prec=0, scale=0");
         }

         [TestMethod]
         public void TestGetDestinationType_When_Varchar2ToVarchar()
         {
-            var destinationType = GetDestinationType("varchar2(@Length)", 25, 0, 0);
-            destinationType.Should().Be("varchar(25)");
+            _length = 25;
+            var destinationType = GetDestinationType("varchar2(@Length)", ref _length, ref _prec, ref _scale);
+            destinationType.Should().Be("varchar");
+            _length.Should().Be(25);
         }

         [TestMethod]
         public void TestGetDestinationType_When_VarcharToVarchar()
         {
-            var destinationType = GetDestinationType("varchar(@Length)", 25, 0, 0);
-            destinationType.Should().Be("varchar(25)");
+            _length = 25;
+            var destinationType = GetDestinationType("varchar(@Length)", ref _length, ref _prec, ref _scale);
+            destinationType.Should().Be("varchar");
+            _length.Should().Be(25);
         }

         [TestMethod]
         public void TestGetDestinationType_When_CharToVarchar()
         {
-            var destinationType = GetDestinationType("char(@Length)", 25, 0, 0);
-            destinationType.Should().Be("varchar(25)");
+            _length = 25;
+            var destinationType = GetDestinationType("char(@Length)", ref _length, ref _prec, ref _scale);
+            destinationType.Should().Be("varchar");
+            _length.Should().Be(25);
         }

         [TestMethod]
         public void TestGetDestinationType_When_ClobToLongText()
         {
-            var destinationType = GetDestinationType("clob", 0, 0, 0);
+            var destinationType = GetDestinationType("clob", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("longtext");
         }

         [TestMethod]
         public void TestGetDestinationType_When_NumberToBool()
         {
-            var destinationType = GetDestinationType("number(@Prec,@Scale)", 0, 1, 0);
+            _prec = 1;
+            var destinationType = GetDestinationType("number(@Prec,@Scale)", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("bool");
         }

         [TestMethod]
         public void TestGetDestinationType_When_NumberToInt8()
         {
-            var destinationType = GetDestinationType("number(@Prec,@Scale)", 0, 3, 0);
+            _prec = 3;
+            var destinationType = GetDestinationType("number(@Prec,@Scale)", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("int8");
         }

         [TestMethod]
         public void TestGetDestinationType_When_NumberToInt16()
         {
-            var destinationType = GetDestinationType("number(@Prec,@Scale)", 0, 5, 0);
+            _prec = 5;
+            var destinationType = GetDestinationType("number(@Prec,@Scale)", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("int16");
         }

         [TestMethod]
         public void TestGetDestinationType_When_NumberToInt()
         {
-            var destinationType = GetDestinationType("number(@Prec,@Scale)", 0, 15, 0);
+            _prec = 15;
+            var destinationType = GetDestinationType("number(@Prec,@Scale)", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("int");
         }

         [TestMethod]
         public void TestGetDestinationType_When_NumberToInt64()
         {
-            var destinationType = GetDestinationType("number(@Prec,@Scale)", 0, 20, 0);
+            _prec = 20;
+            var destinationType = GetDestinationType("number(@Prec,@Scale)", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("int64");
         }

         [TestMethod]
         public void TestGetDestinationType_When_NumberToMoney18_2()
         {
-            var destinationType = GetDestinationType("number(@Prec,@Scale)", 0, 18, 2);
+            _prec = 18;
+            _scale = 2;
+            var destinationType = GetDestinationType("number(@Prec,@Scale)", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("money");
         }

         [TestMethod]
         public void TestGetDestinationType_When_NumberToMoney30_3()
         {
-            var destinationType = GetDestinationType("number(@Prec,@Scale)", 0, 30, 3);
+            _prec = 30;
+            _scale = 3;
+            var destinationType = GetDestinationType("number(@Prec,@Scale)", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("money");
         }

         [TestMethod]
         public void TestGetDestinationType_When_AnyUnrecognizedNumber()
         {
-            var destinationType = GetDestinationType("number(@Prec,@Scale)", 0, 32, 9);
+            _prec = 32;
+            _scale = 9;
+            var destinationType = GetDestinationType("number(@Prec,@Scale)", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("float");
         }

         [TestMethod]
         public void TestGetDestinationType_When_FloatToFloat()
         {
-            var destinationType = GetDestinationType("float", 0, 0, 0);
+            var destinationType = GetDestinationType("float", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("float");
         }

         [TestMethod]
         public void TestGetDestinationType_When_DateToDateTime()
         {
-            var destinationType = GetDestinationType("date", 32, 0, 0);
+            _length = 32;
+            var destinationType = GetDestinationType("date", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("datetime");
         }

         [TestMethod]
         public void TestGetDestinationType_When_BlobToRaw()
         {
-            var destinationType = GetDestinationType("blob", 0, 0, 0);
+            var destinationType = GetDestinationType("blob", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("raw");
         }

         [TestMethod]
         public void TestGetDestinationType_When_Guid()
         {
-            var destinationType = GetDestinationType("raw(@Length)", 16, 0, 0);
+            _length = 16;
+            var destinationType = GetDestinationType("raw(@Length)", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("guid");
         }

         [TestMethod]
         public void TestGetDestinationType_When_LongRawToRaw()
         {
-            var destinationType = GetDestinationType("long raw", 0, 0, 0);
+            var destinationType = GetDestinationType("long raw", ref _length, ref _prec, ref _scale);
             destinationType.Should().Be("raw");
         }
     }


Add textbox and dropdown support

Add textbox and dropdown support

--- osu.Game/Configuration/SettingSourceAttribute.cs
+++ osu.Game/Configuration/SettingSourceAttribute.cs
@@ -8,6 +8,7 @@
 using JetBrains.Annotations;
 using osu.Framework.Bindables;
 using osu.Framework.Graphics;
+using osu.Framework.Graphics.UserInterface;
 using osu.Game.Overlays.Settings;

 namespace osu.Game.Configuration
@@ -40,8 +41,9 @@
             foreach (var property in configProperties)
             {
                 var attr = property.GetCustomAttribute<SettingSourceAttribute>(true);
+                var prop = property.GetValue(obj);

-                switch (property.GetValue(obj))
+                switch (prop)
                 {
                     case BindableNumber<float> bNumber:
                         yield return new SettingsSlider<float>
@@ -78,6 +80,30 @@
                         };

                         break;
+
+                    case Bindable<string> bString:
+                        yield return new SettingsTextBox
+                        {
+                            LabelText = attr.Label,
+                            Bindable = bString
+                        };
+
+                        break;
+
+                    case IBindable bindable:
+
+                        var dropdownType = typeof(SettingsEnumDropdown<>).MakeGenericType(bindable.GetType().GetGenericArguments()[0]);
+
+                        var dropdown = (Drawable)Activator.CreateInstance(dropdownType);
+
+                        dropdown.GetType().GetProperty(nameof(IHasCurrentValue<object>.Current))?.SetValue(dropdown, obj);
+
+                        yield return dropdown;
+
+                        break;
+
+                    default:
+                        throw new InvalidOperationException($"{nameof(SettingSourceAttribute)} was attached to an unsupported type ({prop})");
                 }
             }
         }


remove `#nullable disable`

remove `#nullable disable`

--- osu.Game/Graphics/Containers/UserDimContainer.cs
+++ osu.Game/Graphics/Containers/UserDimContainer.cs
@@ -1,7 +1,5 @@
 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
 // See the LICENCE file in the repository root for full licence text.
-
-#nullable disable

 using System;
 using osu.Framework.Allocation;
@@ -46,13 +44,13 @@
         /// </summary>
         public bool ContentDisplayed { get; private set; }

-        protected Bindable<double> UserDimLevel { get; private set; }
+        protected Bindable<double> UserDimLevel { get; private set; } = null!;

         public Bindable<float> DimAmount { get; set; } = new Bindable<float>();

-        protected Bindable<bool> LightenDuringBreaks { get; private set; }
+        protected Bindable<bool> LightenDuringBreaks { get; private set; } = null!;

-        protected Bindable<bool> ShowStoryboard { get; private set; }
+        protected Bindable<bool> ShowStoryboard { get; private set; } = null!;

         private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? BREAK_LIGHTEN_AMOUNT : 0;


oops fix build

oops fix build

--- src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs
+++ src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs
@@ -35,7 +35,6 @@
             Add<AuditItemMapper>();
             Add<ContentMapper>();
             Add<ContentTypeMapper>();
-            Add<SimpleContentTypeMapper>();
             Add<DataTypeMapper>();
             Add<DictionaryMapper>();
             Add<DictionaryTranslationMapper>();


Compilation fixes

Compilation fixes

--- src/UnityExtension/Assets/Editor/GitHub.Unity/UI/GitPathView.cs
+++ src/UnityExtension/Assets/Editor/GitHub.Unity/UI/GitPathView.cs
@@ -64,14 +64,17 @@
                             isBusy = true;

                             var validateGitInstall = !string.IsNullOrEmpty(newValue);
+                            if (validateGitInstall)
+                            {
+                                var nPath = newValue.ToNPath();
+                                if (!nPath.FileExists())
+                                {
+                                    EditorUtility.DisplayDialog(GitInstallPickInvalidTitle,
+                                        String.Format(GitInstallPickInvalidMessage, newValue),
+                                        GitInstallPickInvalidOK);

-                            if (validateGitInstall && !GitClient.ValidateGitInstall(newValue.ToNPath()))
-                            {
-                                EditorUtility.DisplayDialog(GitInstallPickInvalidTitle,
-                                    String.Format(GitInstallPickInvalidMessage, newValue),
-                                    GitInstallPickInvalidOK);
-
-                                validateGitInstall = false;
+                                    validateGitInstall = false;
+                                }
                             }

                             if (validateGitInstall)


Checking for the final node to make sure it is active

--- src/UnityExtension/Assets/Editor/GitHub.Unity/UI/TreeControl.cs
+++ src/UnityExtension/Assets/Editor/GitHub.Unity/UI/TreeControl.cs
@@ -91,10 +91,16 @@
                     var alreadyExists = folders.ContainsKey(name);
                     if (!alreadyExists)
                     {
+                        var isActive = false;
+                        if (name == d.Name)
+                        {
+                            isActive = d.IsActive;
+                        }
+
                         var node = new TreeNode
                         {
                             Name = name,
-                            IsActive = d.IsActive,
+                            IsActive = isActive,
                             Label = label,
                             Level = level,
                             IsFolder = isFolder


Starting to ripple the checked state up through the tree

--- src/UnityExtension/Assets/Editor/GitHub.Unity/UI/TreeControl.cs
+++ src/UnityExtension/Assets/Editor/GitHub.Unity/UI/TreeControl.cs
@@ -259,24 +259,83 @@

         private void ToggleNodeCheck(int idx, TreeNode node)
         {
+            var isChecked = false;
+
+            switch (node.CheckState)
+            {
+                case CheckState.Mixed:
+                case CheckState.Empty:
+                    node.CheckState = CheckState.Checked;
+                    isChecked = true;
+                    break;
+
+                case CheckState.Checked:
+                    node.CheckState = CheckState.Empty;
+                    break;
+            }
+
             if (node.IsFolder)
             {
-
-            }
-            else
-            {
-                switch (node.CheckState)
-                {
-                    case CheckState.Empty:
-                        node.CheckState = CheckState.Checked;
-                        break;
-
-                    case CheckState.Checked:
-                        node.CheckState = CheckState.Empty;
-                        break;
-                }
-
-                Debug.LogFormat("Ripple CheckState index:{0} level:{1}", idx, node.Level);
+
+            }
+
+            ToggleParentFolders(idx, node, isChecked);
+        }
+
+        private void ToggleParentFolders(int idx, TreeNode node, bool isChecked)
+        {
+            while (true)
+            {
+                if (node.Level > 0)
+                {
+                    Debug.Log("ToggleParentFolders");
+
+                    var siblingsInSameState = true;
+                    var firstSiblingIndex = idx;
+
+                    Debug.LogFormat("Ripple CheckState index:{0} level:{1}", idx, node.Level);
+
+                    for (var i = idx - 1; i > 0 && nodes[i].Level == node.Level; i--)
+                    {
+                        firstSiblingIndex = i;
+                        var siblingIsChecked = nodes[i].CheckState == CheckState.Checked;
+                        Debug.LogFormat("Previous Sibling - idx:{0} name:{1} checked:{2}", i, nodes[i].Path, siblingIsChecked);
+
+                        if (isChecked != siblingIsChecked)
+                        {
+                            siblingsInSameState = false;
+                            //break;
+                        }
+                    }
+
+                    //if (siblingsInSameState)
+                    {
+                        for (var i = idx + 1; i < nodes.Count && nodes[i].Level == node.Level; i++)
+                        {
+                            var siblingIsChecked = nodes[i].CheckState == CheckState.Checked;
+                            Debug.LogFormat("Next Siblings    - idx:{0} name:{1} checked:{2}", i, nodes[i].Path, siblingIsChecked);
+                        }
+                    }
+
+                    Debug.LogFormat("Siblings in same state = {0}", siblingsInSameState);
+
+                    var parentIndex = firstSiblingIndex - 1;
+                    var parentNode = nodes[parentIndex];
+                    if (siblingsInSameState)
+                    {
+                        parentNode.CheckState = isChecked ? CheckState.Checked : CheckState.Empty;
+                    }
+                    else
+                    {
+                        parentNode.CheckState = CheckState.Mixed;
+                    }
+
+                    idx = parentIndex;
+                    node = parentNode;
+                    continue;
+                }
+
+                break;
             }
         }


NaN is false, not true.

NaN is false, not true.

--- src/Hprose.IO/Deserializers/BooleanDeserializer.cs
+++ src/Hprose.IO/Deserializers/BooleanDeserializer.cs
@@ -12,7 +12,7 @@
  *                                                        *
  * BooleanDeserializer class for C#.                      *
  *                                                        *
- * LastModified: Apr 10, 2018                             *
+ * LastModified: Dec 16, 2018                             *
  * Author: Ma Bingyao <andot@hprose.com>                  *
  *                                                        *
 \**********************************************************/
@@ -27,10 +27,10 @@
             var stream = reader.Stream;
             switch (tag) {
                 case TagTrue:
-                case TagNaN:
                     return true;
                 case TagFalse:
                 case TagEmpty:
+                case TagNaN:
                 case '0':
                     return false;
                 case TagInteger:


[CosmosDB] fixing javascript output binding

--- src/WebJobs.Extensions.CosmosDB/Config/CosmosDBConfiguration.cs
+++ src/WebJobs.Extensions.CosmosDB/Config/CosmosDBConfiguration.cs
@@ -67,6 +67,8 @@

             IBindingProvider outputProvider = factory.BindToCollector<CosmosDBAttribute, OpenType>(typeof(CosmosDBCollectorBuilder<>), this);

+            IBindingProvider outputProviderJObject = factory.BindToCollector<CosmosDBAttribute, JObject>(typeof(CosmosDBCollectorBuilder<>), this);
+
             IBindingProvider clientProvider = factory.BindToInput<CosmosDBAttribute, DocumentClient>(new CosmosDBClientBuilder(this));

             IBindingProvider jArrayProvider = factory.BindToInput<CosmosDBAttribute, JArray>(typeof(CosmosDBJArrayBuilder), this);
@@ -77,8 +79,11 @@
             IBindingProvider inputProvider = factory.BindToGenericValueProvider<CosmosDBAttribute>((attr, t) => BindForItemAsync(attr, t));
             inputProvider = factory.AddValidator<CosmosDBAttribute>(ValidateInputBinding, inputProvider);

+            context.AddBindingRule<CosmosDBAttribute>()
+                .AddConverter<JObject, JObject>(s => s);
+
             IExtensionRegistry extensions = context.Config.GetService<IExtensionRegistry>();
-            extensions.RegisterBindingRules<CosmosDBAttribute>(ValidateConnection, nameResolver, outputProvider, clientProvider, jArrayProvider, enumerableProvider, inputProvider);
+            extensions.RegisterBindingRules<CosmosDBAttribute>(ValidateConnection, nameResolver, outputProvider, outputProviderJObject, clientProvider, jArrayProvider, enumerableProvider, inputProvider);

             context.Config.RegisterBindingExtensions(new CosmosDBTriggerAttributeBindingProvider(nameResolver, this, LeaseOptions));
         }


remove redundant test

remove redundant test

--- src/JsonLD.Entities.Tests/EntitySerializerTests.cs
+++ src/JsonLD.Entities.Tests/EntitySerializerTests.cs
@@ -141,19 +141,5 @@
             // then
             Assert.That(deserialized.UriProperty, Is.Null);
         }
-
-        [Test]
-        public void Should_serialize_boolean_correctly()
-        {
-            // given
-            var obj = new { Value = true };
-
-            // when
-            dynamic ld = _serializer.Serialize(obj);
-
-            // then
-            object value = ld.value;
-            Assert.That(value.ToString(), Is.EqualTo("true"));
-        }
     }
 }


We can use the CLR's Delete recursive

We can use the CLR's Delete recursive

--- src/Lucene.Net.Tests/core/Store/TestWindowsMMap.cs
+++ src/Lucene.Net.Tests/core/Store/TestWindowsMMap.cs
@@ -101,17 +101,13 @@
             RmDir(dirPath);
         }

-        private void RmDir(DirectoryInfo dir)
+        private static void RmDir(DirectoryInfo dir)
         {
             if (!dir.Exists)
             {
                 return;
             }
-            foreach (FileInfo file in dir.GetFiles())
-            {
-                file.Delete();
-            }
-            dir.Delete();
+            dir.Delete(true);
         }
     }
 }


Fix a missing async regeneration in #2081

--- src/NHibernate.Test/Async/Hql/EntityJoinHqlTest.cs
+++ src/NHibernate.Test/Async/Hql/EntityJoinHqlTest.cs
@@ -497,7 +497,7 @@
 				{
 					rc.Id(e => e.Id, m => m.Generator(Generators.GuidComb));
 					rc.Property(e => e.Name);
-					rc.Property(e => e.PropertyRef);
+					rc.Property(e => e.PropertyRef, m => m.Column("EntityPropertyRef"));
 				});

 			mapper.Class<NullableOwner>(
@@ -510,6 +510,7 @@
 						e => e.PropRef,
 						m =>
 						{
+							m.Column("OwnerPropertyRef");
 							m.PropertyRef(nameof(PropRefEntity.PropertyRef));
 							m.ForeignKey("none");
 							m.NotFound(NotFoundMode.Ignore);


Log with local time and UTC offset

Log with local time and UTC offset

--- src/NewsReader/NewsReader.Presentation/App.xaml.cs
+++ src/NewsReader/NewsReader.Presentation/App.xaml.cs
@@ -61,7 +61,7 @@

         protected override void OnStart()
         {
-            Log.Default.Info("App started ({0}, {1}) on {2}", appInfoService.AppName, appInfoService.VersionString, DateTime.UtcNow.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
+            Log.Default.Info("App started ({0}, {1}) on {2}", appInfoService.AppName, appInfoService.VersionString, DateTime.Now.ToString("yyyy'-'MM'-'dd' 'HH':'mm':'ssK", CultureInfo.InvariantCulture));
             string? appSecret = null;
             GetAppCenterSecret(ref appSecret);
             if (appSecret != null) AppCenter.Start(appSecret, typeof(Analytics), typeof(Crashes));


improved MsBuild selection

improved MsBuild selection

--- src/OmniSharp.Host/MSBuild/Discovery/Extensions.cs
+++ src/OmniSharp.Host/MSBuild/Discovery/Extensions.cs
@@ -7,7 +7,7 @@
     {
         public static void RegisterDefaultInstance(this IMSBuildLocator msbuildLocator, ILogger logger)
         {
-            var bestInstanceFound = GetBestInstance(msbuildLocator, out var invalidVSFound);
+            var bestInstanceFound = GetBestInstance(msbuildLocator, logger, out var invalidVSFound);

             if (bestInstanceFound != null)
             {
@@ -16,8 +16,8 @@
                 if (invalidVSFound && bestInstanceFound.DiscoveryType == DiscoveryType.StandAlone)
                 {
                     logger.LogWarning(
-                        @"It looks like you have Visual Studio 2017 RTM installed.
- Try updating Visual Studio 2017 to the most recent release to enable better MSBuild support."
+                        @"It looks like you have Visual Studio 2019 RTM installed.
+ Try updating Visual Studio 2019 to the most recent release to enable better MSBuild support."
                     );
                 }

@@ -52,7 +52,7 @@
                 && (instance.DiscoveryType == DiscoveryType.DeveloperConsole
                     || instance.DiscoveryType == DiscoveryType.VisualStudioSetup);

-        public static MSBuildInstance GetBestInstance(this IMSBuildLocator msbuildLocator, out bool invalidVSFound)
+        public static MSBuildInstance GetBestInstance(this IMSBuildLocator msbuildLocator, ILogger logger, out bool invalidVSFound)
         {
             invalidVSFound = false;
             MSBuildInstance bestMatchInstance = null;
@@ -62,10 +62,12 @@
             {
                 var score = GetInstanceFeatureScore(instance);

+                logger.LogDebug($"MSBuild instance {instance.Name} {instance.Version} scored at {score}");
+
                 invalidVSFound = invalidVSFound || instance.IsInvalidVisualStudio();

-                if (score > bestMatchScore
-                    || (score == bestMatchScore && instance.Version.Major > (bestMatchInstance?.Version.Major ?? 0)))
+                if (score > bestMatchScore ||
+                    score == bestMatchScore && instance.Version > bestMatchInstance?.Version)
                 {
                     bestMatchInstance = instance;
                     bestMatchScore = score;


Document code generation.

Document code generation.

--- MsgPack.Strict/StrictDeserialiser.cs
+++ MsgPack.Strict/StrictDeserialiser.cs
@@ -129,11 +129,17 @@

             var mapSize = ilg.DeclareLocal(typeof(long));
             {
-                // read its length
+                // MsgPack messages may be single values, arrays, maps, or any arbitrary
+                // combination of these types. Our convention is to require messages to
+                // be encoded as maps where the key is the property name.
+                //
+                // MsgPack maps begin with a header indicating the number of pairs
+                // within the map. We read this here.
                 ilg.Emit(OpCodes.Ldarg_0); // unpacker
                 ilg.Emit(OpCodes.Ldloca, mapSize);
                 ilg.Emit(OpCodes.Callvirt, typeof(Unpacker).GetMethod("ReadMapLength"));
-                // return value should be true
+
+                // If false was returned, the data stream ended
                 var ifLabel = ilg.DefineLabel();
                 ilg.Emit(OpCodes.Brtrue, ifLabel);
                 {
@@ -145,30 +151,34 @@

             #endregion

-            // for each item in map
-            {
-                // var loopIndex;
+            // For each key/value pair in the map...
+            {
+                // Create a loop counter, initialised to zero
                 var loopIndex = ilg.DeclareLocal(typeof(long));
-                // loopIndex = 0;
                 ilg.Emit(OpCodes.Ldc_I4_0);
                 ilg.Emit(OpCodes.Conv_I8);
                 ilg.Emit(OpCodes.Stloc, loopIndex);

-                var lblLoopTest = ilg.DefineLabel();
-                var lblLoopExit = ilg.DefineLabel();
-                var lblLoopStart = ilg.DefineLabel();
-
+                // Create labels to jump to within the loop
+                var lblLoopTest = ilg.DefineLabel();   // Comparing counter to map size
+                var lblLoopExit = ilg.DefineLabel();   // The first instruction after the loop
+                var lblLoopStart = ilg.DefineLabel();  // The first instruction within the loop
+
+                // Run the test first
                 ilg.Emit(OpCodes.Br, lblLoopTest);

+                // Mark the first instruction within the loop
                 ilg.MarkLabel(lblLoopStart);

-                // read the key
+                // Although MsgPack allows map keys to be of any arbitrary type, our convention
+                // is to require keys to be strings. We read the key here.
                 var key = ilg.DeclareLocal(typeof(string));
                 {
                     ilg.Emit(OpCodes.Ldarg_0); // unpacker
                     ilg.Emit(OpCodes.Ldloca, key);
                     ilg.Emit(OpCodes.Callvirt, typeof(Unpacker).GetMethod("ReadString"));
-                    // return value should be true
+
+                    // If false was returned, the data stream ended
                     var ifLabel = ilg.DefineLabel();
                     ilg.Emit(OpCodes.Brtrue, ifLabel);
                     {
@@ -180,30 +190,36 @@
                     ilg.MarkLabel(ifLabel);
                 }

+                // Build a chain of if/elseif/elseif... blocks for each of the expected fields.
+                // It could be slightly more efficient here to generate a O(log(N)) tree-based lookup,
+                // but that would take quite some engineering. Let's see if there's a significant perf
+                // hit here or not first.
                 Label? nextLabel = null;
                 for (var parameterIndex = 0; parameterIndex < parameters.Length; parameterIndex++)
                 {
-                    // wire up labels between consecutive cascading if/elif/elif... blocks
+                    // Mark the beginning of the next block, as used if the previous block's condition failed
                     if (nextLabel != null)
                         ilg.MarkLabel(nextLabel.Value);
                     nextLabel = ilg.DefineLabel();

-                    // compare map's key with this parameter's name in a case insensitive way
+                    // Compare map's key with this parameter's name in a case insensitive way
                     ilg.Emit(OpCodes.Ldloc, key);
                     ilg.Emit(OpCodes.Ldstr, parameters[parameterIndex].Name);
                     ilg.Emit(OpCodes.Ldc_I4_5);
                     ilg.Emit(OpCodes.Callvirt, typeof(string).GetMethod("Equals", new[] {typeof(string), typeof(StringComparison)}));

-                    // if the key doesn't match this property, go to the next block
+                    // If the key doesn't match this property, go to the next block
                     ilg.Emit(OpCodes.Brfalse, nextLabel.Value);

-                    // read value
+                    // Read value
                     MethodInfo methodInfo;
                     if (!_typeGetters.TryGetValue(parameters[parameterIndex].ParameterType, out methodInfo))
                         throw new NotImplementedException();

-                    // verify we haven't already seen a value for this parameter
+                    // Verify we haven't already seen a value for this parameter
                     {
+                        // Mask out the LSb and see if it is set. If so, we've seen this property
+                        // already in this message, which is invalid.
                         ilg.Emit(OpCodes.Ldloc, valueSetLocals[parameterIndex]);
                         ilg.Emit(OpCodes.Ldc_I4_1);
                         ilg.Emit(OpCodes.And);
@@ -218,21 +234,21 @@

                         ilg.MarkLabel(notSeenLabel);

-                        // set 'seen' to true
+                        // Record the fact that we've seen this property
                         ilg.Emit(OpCodes.Ldloc, valueSetLocals[parameterIndex]);
                         ilg.Emit(OpCodes.Ldc_I4_1);
                         ilg.Emit(OpCodes.Or);
                         ilg.Emit(OpCodes.Stloc, valueSetLocals[parameterIndex]);
                     }

-                    // the 'type getter' expects the unpacker on the stack
+                    // The 'type getter' expects, on the stack, the unpacker and the address of the value to store to.
                     ilg.Emit(OpCodes.Ldarg_0); // unpacker
                     ilg.Emit(OpCodes.Ldloca, valueLocals[parameterIndex]);
+
+                    // Invoke the 'type getter', which pushes true (success) or false (failure)
                     ilg.Emit(OpCodes.Call, methodInfo);

-                    // the 'type getter' pushes true or false
-
-                    // TODO if fail, throw
+                    // If the 'type getter' failed, throw
                     {
                         var typeGetterSuccess = ilg.DefineLabel();
                         ilg.Emit(OpCodes.Brtrue, typeGetterSuccess);
@@ -249,24 +265,28 @@
                 if (nextLabel != null)
                     ilg.MarkLabel(nextLabel.Value);

-                // increment the loop index
+                // Increment the loop index
                 ilg.Emit(OpCodes.Ldloc, loopIndex);
                 ilg.Emit(OpCodes.Ldc_I4_1);
                 ilg.Emit(OpCodes.Conv_I8);
                 ilg.Emit(OpCodes.Add);
                 ilg.Emit(OpCodes.Stloc, loopIndex);

-                // test loop condition
+                // Loop condition
                 ilg.MarkLabel(lblLoopTest);
                 ilg.Emit(OpCodes.Ldloc, loopIndex);
                 ilg.Emit(OpCodes.Ldloc, mapSize);
+                // If the loop is done, jump to the first instruction after the loop
                 ilg.Emit(OpCodes.Beq, lblLoopExit);

+                // Jump back to the start of the loop
                 ilg.Emit(OpCodes.Br, lblLoopStart);
+
+                // Mark the end of the loop
                 ilg.MarkLabel(lblLoopExit);
             }

-            #region Verify all required values specified
+            #region Verify all required values either specified or have a default value

             ilg.Emit(OpCodes.Ldc_I4_1);
             foreach (var valueSetLocal in valueSetLocals)
@@ -286,12 +306,17 @@

             #endregion

+            // Push all values onto the execution stack
             foreach (var valueLocal in valueLocals)
                 ilg.Emit(OpCodes.Ldloc, valueLocal);
+
+            // Call the target type's constructor
             ilg.Emit(OpCodes.Newobj, ctor);

+            // Return the newly constructed object!
             ilg.Emit(OpCodes.Ret);

+            // Return a delegate that performs the above operations
             return (Func<Unpacker, object>)method.CreateDelegate(typeof(Func<Unpacker, object>));
         }


Remove shared state

Remove shared state

Make each InMemoryResultPublisher instance have its own state, rather than each instance just wrap shared static state.

--- src/Scientist/Internals/InMemoryResultPublisher.cs
+++ src/Scientist/Internals/InMemoryResultPublisher.cs
@@ -8,8 +8,8 @@
 {
     public class InMemoryResultPublisher : IResultPublisher
     {
-        readonly static Task _completed = Task.FromResult(0);
-        readonly static ConcurrentDictionary<int, ConcurrentBag<object>> _results
+        readonly Task _completed = Task.FromResult(0);
+        readonly ConcurrentDictionary<int, ConcurrentBag<object>> _results
             = new ConcurrentDictionary<int, ConcurrentBag<object>>();

         static int GetKey<T, TClean>()


- check duplicate token properties

- check duplicate token properties

--- NetLicensingClient/Entities/Token.cs
+++ NetLicensingClient/Entities/Token.cs
@@ -42,7 +42,10 @@
                 if (!base.setFromProperty(p)) // Not BaseEntity property?
                 {
                     // custom property
-                    tokenProperties.Add(p.name, p.Value);
+                    if (!tokenProperties.ContainsKey(p.name))
+                    {
+                        tokenProperties.Add(p.name, p.Value);
+                    }
                 }
             }
         }


http://172.19.115.33:80/Appclusive/api/Core/Customers?$expand=Tenants does still not deliver tenants -> loaded them separately close #67

--- src/biz.dfch.CS.Appclusive.UI/Controllers/CustomerController.cs
+++ src/biz.dfch.CS.Appclusive.UI/Controllers/CustomerController.cs
@@ -23,7 +23,12 @@
             try
             {
                 var item = CoreRepository.Customers.Expand("ContractMappings").Expand("Tenants").Expand("CreatedBy").Expand("ModifiedBy").Where(c => c.Id == id).FirstOrDefault();
-                return View(AutoMapper.Mapper.Map<Models.Core.Customer>(item));
+                Models.Core.Customer modelItem = AutoMapper.Mapper.Map<Models.Core.Customer>(item);
+                if (null != modelItem)
+                {
+                    modelItem.Tenants = LoadTenants(id, 1);
+                }
+                return View(modelItem);
             }
             catch (Exception ex)
             {
@@ -71,7 +76,12 @@
             try
             {
                 var apiItem = CoreRepository.Customers.Expand("ContractMappings").Expand("Tenants").Expand("CreatedBy").Expand("ModifiedBy").Where(c => c.Id == id).FirstOrDefault();
-                return View(AutoMapper.Mapper.Map<Models.Core.Customer>(apiItem));
+                Models.Core.Customer modelItem = AutoMapper.Mapper.Map<Models.Core.Customer>(apiItem);
+                if (null != modelItem)
+                {
+                    modelItem.Tenants = LoadTenants(id, 1);
+                }
+                return View(modelItem);
             }
             catch (Exception ex)
             {
@@ -104,7 +114,13 @@
                     CoreRepository.UpdateObject(apiItem);
                     CoreRepository.SaveChanges();
                     ((List<AjaxNotificationViewModel>)ViewBag.Notifications).Add(new AjaxNotificationViewModel(ENotifyStyle.success, "Successfully saved"));
-                    return View(AutoMapper.Mapper.Map<Models.Core.Customer>(apiItem));
+
+                    Models.Core.Customer modelItem = AutoMapper.Mapper.Map<Models.Core.Customer>(apiItem);
+                    if (null != modelItem)
+                    {
+                        modelItem.Tenants = LoadTenants(id, 1);
+                    }
+                    return View(modelItem);
                 }
             }
             catch (Exception ex)
@@ -135,6 +151,12 @@
         }

+        private List<Models.Core.Tenant> LoadTenants(long customerId, int pageNr)
+        {
+            List<Api.Core.Tenant> items = CoreRepository.Tenants.Where(t=>t.CustomerId==customerId).ToList();
+            return AutoMapper.Mapper.Map<List<Models.Core.Tenant>>(items);
+        }
+
         #endregion

     }


tests: refactor tests RegisterPostEvictionCallback

--- LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs
+++ LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs
@@ -800,10 +800,10 @@
                 TestKey,
             entry =>
             {
-                entry.RegisterPostEvictionCallback((key, value, reason, state) => callbackHasFired = true);
                 return new ComplexTestObject();
             }, new MemoryCacheEntryOptions()
-                    .AddExpirationToken(expireToken));
+                    .AddExpirationToken(expireToken)
+                    .RegisterPostEvictionCallback((key, value, reason, state) => callbackHasFired = true));
             // trigger expiry
             Thread.Sleep(TimeSpan.FromMilliseconds(millisecondsCacheDuration + 50));

@@ -820,9 +820,10 @@
                 TestKey,
                 entry =>
                 {
-                    entry.RegisterPostEvictionCallback((key, value, reason, state) => callbackHasFired = true);
                     return new ComplexTestObject();
-                }, LazyCacheEntryOptions.WithImmediateAbsoluteExpiration(TimeSpan.FromMilliseconds(millisecondsCacheDuration)));
+                }, LazyCacheEntryOptions
+                    .WithImmediateAbsoluteExpiration(TimeSpan.FromMilliseconds(millisecondsCacheDuration))
+                    .RegisterPostEvictionCallback((key, value, reason, state) => callbackHasFired = true));
             // trigger expiry
             Thread.Sleep(TimeSpan.FromMilliseconds(millisecondsCacheDuration + 50));

@@ -839,9 +840,10 @@
                 TestKey,
                 entry =>
                 {
-                    entry.RegisterPostEvictionCallback((key, value, reason, state) => callbackHasFired = true);
                     return Task.FromResult(new ComplexTestObject());
-                }, LazyCacheEntryOptions.WithImmediateAbsoluteExpiration(TimeSpan.FromMilliseconds(millisecondsCacheDuration)));
+                }, LazyCacheEntryOptions
+                    .WithImmediateAbsoluteExpiration(TimeSpan.FromMilliseconds(millisecondsCacheDuration))
+                    .RegisterPostEvictionCallback((key, value, reason, state) => callbackHasFired = true));
             // trigger expiry
             Thread.Sleep(TimeSpan.FromMilliseconds(millisecondsCacheDuration + 50));


Fix for ParamsArray support

Fix for ParamsArray support

--- NiL.JS/Core/Functions/MethodProxy.cs
+++ NiL.JS/Core/Functions/MethodProxy.cs
@@ -193,11 +193,6 @@
                             Expression.Return(returnLabel, Expression.Assign(tempValue, resultArray)),
                             arrayAssignArgObj))),
                 Expression.Block(
-                    Expression.IfThen(
-                        Expression.Equal(Expression.ArrayLength(arguments), Expression.Constant(_parameters.Length)),
-                        Expression.Block(
-                            Expression.Assign(tempValue, getValueExp),
-                            Expression.IfThen(Expression.NotEqual(tempValue, Expression.Constant(null)), Expression.Return(returnLabel, tempValue)))),
                     Expression.Assign(resultArray, Expression.New(resultArrayCtor, Expression.Subtract(Expression.ArrayLength(arguments), argumentIndex))),
                     Expression.Loop(
                             Expression.IfThenElse(conditionExp,
@@ -570,7 +565,7 @@
                 return _paramsConverters[index].To(value);

             var strictConversion = options.HasFlag(ConvertArgsOptions.StrictConversion);
-            var processRest = _restPrmsArrayCreator != null && index >= _parameters.Length - 1 && (value.ValueType != JSValueType.Object || !(value.Value is BaseLibrary.Array));
+            var processRest = _restPrmsArrayCreator != null && index >= _parameters.Length - 1 && (index >= _parameters.Length || value.ValueType != JSValueType.Object || !(value.Value is BaseLibrary.Array));
             var parameterInfo = processRest ? _parameters[_parameters.Length - 1] : _parameters[index];
             var parameterType = processRest ? parameterInfo.ParameterType.GetElementType() : parameterInfo.ParameterType;
             object result = null;


Changed selfhost to throw in case we get a WCF message that does not contain a request. In this case there is nothing we can do and so throwing seems like the right thing,

--- src/System.Web.Http.SelfHost/HttpSelfHostServer.cs
+++ src/System.Web.Http.SelfHost/HttpSelfHostServer.cs
@@ -149,8 +149,7 @@
             HttpRequestMessage request = requestContext.RequestMessage.ToHttpRequestMessage();
             if (request == null)
             {
-                Error.InvalidOperation(SRResources.HttpMessageHandlerInvalidMessage, requestContext.RequestMessage.GetType());
-                return;
+                throw Error.InvalidOperation(SRResources.HttpMessageHandlerInvalidMessage, requestContext.RequestMessage.GetType());
             }

             // create principal information and add it the request for the windows auth case


Simplified SSO authentication unit tests.

--- Libraries/MFaaP.MFWSClient.Tests/MFWSClient.Authentication.cs
+++ Libraries/MFaaP.MFWSClient.Tests/MFWSClient.Authentication.cs
@@ -141,24 +141,10 @@
 			var runner = new RestApiTestRunner<PrimitiveType<string>>(Method.POST, "/REST/server/authenticationtokens");

 			// When the execute method is called, return a dummy authentication token.
-			runner.RestClientMock
-				.Setup(c => c.ExecuteTaskAsync<PrimitiveType<string>>(It.IsAny<IRestRequest>(), It.IsAny<CancellationToken>()))
-				// Return a mock response.
-				.Returns(() =>
-				{
-					// Create the mock response.
-					var response = new Mock<IRestResponse<PrimitiveType<string>>>();
-
-					// Setup the return data.
-					response.SetupGet(r => r.Data)
-						.Returns(new PrimitiveType<string>()
-						{
-							Value = "hello world"
-						});
-
-					//Return the mock object.
-					return Task.FromResult(response.Object);
-				});
+			runner.ResponseData = new PrimitiveType<string>()
+			{
+				Value = "hello world"
+			};

 			// Create the object to send in the body.
 			var body = new Authentication
@@ -173,7 +159,7 @@
 			runner.SetExpectedRequestBody(body);

 			// Execute.
-			runner.MFWSClient.AuthenticateUsingCredentials(body.VaultGuid.Value, body.Username, body.Password);
+			runner.MFWSClient.AuthenticateUsingCredentials(body.VaultGuid.Value, body.Username, body.Password, body.Expiration.Value);

 			// Verify.
 			runner.Verify();
@@ -198,24 +184,10 @@
 			var runner = new RestApiTestRunner<PrimitiveType<string>>(Method.POST, "/REST/server/authenticationtokens");

 			// When the execute method is called, return a dummy authentication token.
-			runner.RestClientMock
-				.Setup(c => c.ExecuteTaskAsync<PrimitiveType<string>>(It.IsAny<IRestRequest>(), It.IsAny<CancellationToken>()))
-				// Return a mock response.
-				.Returns(() =>
-				{
-					// Create the mock response.
-					var response = new Mock<IRestResponse<PrimitiveType<string>>>();
-
-					// Setup the return data.
-					response.SetupGet(r => r.Data)
-						.Returns(new PrimitiveType<string>()
-						{
-							Value = "hello world"
-						});
-
-					//Return the mock object.
-					return Task.FromResult(response.Object);
-				});
+			runner.ResponseData = new PrimitiveType<string>()
+			{
+				Value = "hello world"
+			};

 			// Create the object to send in the body.
 			var body = new Authentication
@@ -230,7 +202,7 @@
 			runner.SetExpectedRequestBody(body);

 			// Execute.
-			await runner.MFWSClient.AuthenticateUsingCredentialsAsync(body.VaultGuid.Value, body.Username, body.Password);
+			await runner.MFWSClient.AuthenticateUsingCredentialsAsync(body.VaultGuid.Value, body.Username, body.Password, body.Expiration.Value);

 			// Verify.
 			runner.Verify();


use correct winforms references

use correct winforms references

--- src/Test.Utilities/AdditionalMetadataReferences.cs
+++ src/Test.Utilities/AdditionalMetadataReferences.cs
@@ -40,8 +40,7 @@
         public static ReferenceAssemblies DefaultWithWilson { get; } = Default
             .AddPackages(ImmutableArray.Create(new PackageIdentity("Microsoft.IdentityModel.Tokens", "6.12.0")));

-        public static ReferenceAssemblies DefaultWithWinForms { get; } = Default
-            .AddAssemblies(ImmutableArray.Create("System.Windows.Forms"));
+        public static ReferenceAssemblies DefaultWithWinForms { get; } = ReferenceAssemblies.NetFramework.Net472.WindowsForms;

         public static ReferenceAssemblies DefaultWithWinHttpHandler { get; } = ReferenceAssemblies.NetStandard.NetStandard20
             .AddPackages(ImmutableArray.Create(new PackageIdentity("System.Net.Http.WinHttpHandler", "4.7.0")));


KAL-45 Add detail-type serialization for CloudWatchEvents.

--- Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs
+++ Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs
@@ -2,6 +2,7 @@
 using Newtonsoft.Json.Serialization;
 using System;
 using System.Collections.Generic;
+using System.Reflection;

 namespace Amazon.Lambda.Serialization.Json
 {
@@ -80,6 +81,17 @@
                     }
                 }
             }
+            else if (type.FullName.StartsWith("Amazon.Lambda.CloudWatchEvents.")
+                     && (type.GetTypeInfo().BaseType?.FullName?.StartsWith("CloudWatchEvents.CloudWatchEvent`", StringComparison.Ordinal) ?? false))
+            {
+                foreach (JsonProperty property in properties)
+                {
+                    if (property.PropertyName.Equals("DetailType", StringComparison.Ordinal))
+                    {
+                        property.PropertyName = "detail-type";
+                    }
+                }
+            }

             return properties;
         }


Fixed broken unit test

Fixed broken unit test

--- src/Umbraco.Core/Persistence/PetaPocoExtensions.cs
+++ src/Umbraco.Core/Persistence/PetaPocoExtensions.cs
@@ -74,7 +74,11 @@
             //get all columns but not the primary key if it is auto-incremental
             var cols = string.Join(", ", (
                 from c in pd.Columns
-                where c.Value.ResultColumn == false
+                where
+                    //don't return ResultColumns
+                    !c.Value.ResultColumn
+                    //if the table is auto-incremental, don't return the primary key
+                    && (pd.TableInfo.AutoIncrement && c.Key != pd.TableInfo.PrimaryKey)
                 select tableName + "." + db.EscapeSqlIdentifier(c.Key))
                 .ToArray());

@@ -87,10 +91,10 @@
                 var values = new List<string>();
                 foreach (var i in pd.Columns)
                 {
-                    //if (pd.TableInfo.AutoIncrement && i.Key == pd.TableInfo.PrimaryKey)
-                    //{
-                    //    continue;
-                    //}
+                    if (pd.TableInfo.AutoIncrement && i.Key == pd.TableInfo.PrimaryKey)
+                    {
+                        continue;
+                    }
                     values.Add(string.Format("{0}{1}", "@", index++));
                     db.AddParam(cmd, i.Value.GetValue(poco), "@");
                 }


Extend error message with possible solution (#12962)

Co-authored-by: Zeegaan <5b0406b9f272cfdaa6bcba60e334d6e9437f87dd@umbraco.dk>

--- src/Umbraco.PublishedCache.NuCache/ContentCache.cs
+++ src/Umbraco.PublishedCache.NuCache/ContentCache.cs
@@ -243,7 +243,7 @@
             IPublishedContent? rootNode = GetByRoute(preview, "/", true);
             if (rootNode == null)
             {
-                throw new Exception("Failed to get node at /.");
+                throw new Exception("Failed to get node at /. This might be because you're trying to publish a variant, with no domains setup");
             }

             // remove only if we're the default node


Refactored the ModelBindingExceptionFilter to also handle InvalidCastException, and also ensure the models are the same type. Otherwise a infinite loop was introduced, when requesting a wrong model in the view. Also refactored the why we do the retry from Html to Http headers

--- src/Umbraco.Web/Mvc/ModelBindingExceptionFilter.cs
+++ src/Umbraco.Web/Mvc/ModelBindingExceptionFilter.cs
@@ -1,23 +1,54 @@
-using System.Web.Mvc;
+using System;
+using System.Net;
+using System.Text.RegularExpressions;
+using System.Web.Mvc;

 namespace Umbraco.Web.Mvc
 {
     ///
-    /// An exception filter checking if we get a <see cref="ModelBindingException"/> in which case it returns the html to auto refresh the page
+    ///     An exception filter checking if we get a <see cref="ModelBindingException" /> or <see cref="InvalidCastException" /> with the same model. in which case it returns a redirect to the same page after 1 sec.
     ///
     internal class ModelBindingExceptionFilter : FilterAttribute, IExceptionFilter
     {
+        private static readonly Regex GetPublishedModelsTypesRegex = new Regex("Umbraco.Web.PublishedModels.(\\w+)", RegexOptions.Compiled);
+
         public void OnException(ExceptionContext filterContext)
         {
-            if (!filterContext.ExceptionHandled && filterContext.Exception is ModelBindingException)
+            if (!filterContext.ExceptionHandled
+                && ((filterContext.Exception is ModelBindingException || filterContext.Exception is InvalidCastException)
+                    && IsMessageAboutTheSameModelType(filterContext.Exception.Message)))
             {
-                filterContext.Result = new ContentResult
-                {
-                    Content = "<meta http-equiv=\"refresh\" content=\"3\" />
Loading page...
",
-                    ContentType = "text/html"
-                };
+                filterContext.HttpContext.Response.Headers.Add(HttpResponseHeader.RetryAfter.ToString(), "1");
+                filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.RawUrl, false);
+
                 filterContext.ExceptionHandled = true;
             }
         }
+
+        ///
+        ///     Returns true if the message is about two models with the same name.
+        ///
+        /// <remarks>
+        ///     Message could be something like:
+        /// <para>
+        ///     InvalidCastException:
+        ///     [A]Umbraco.Web.PublishedModels.Home cannot be cast to [B]Umbraco.Web.PublishedModels.Home. Type A originates from 'App_Web_all.generated.cs.8f9494c4.rtdigm_z, Version=0.0.0.3, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Users\User\AppData\Local\Temp\Temporary ASP.NET Files\root\c5c63f4d\c168d9d4\App_Web_all.generated.cs.8f9494c4.rtdigm_z.dll'. Type B originates from 'App_Web_all.generated.cs.8f9494c4.rbyqlplu, Version=0.0.0.5, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Users\User\AppData\Local\Temp\Temporary ASP.NET Files\root\c5c63f4d\c168d9d4\App_Web_all.generated.cs.8f9494c4.rbyqlplu.dll'.
+        ///</para>
+        /// <para>
+        ///     ModelBindingException:
+        ///     Cannot bind source content type Umbraco.Web.PublishedModels.Home to model type Umbraco.Web.PublishedModels.Home. Both view and content models are PureLive, with different versions. The application is in an unstable state and is going to be restarted. The application is restarting now.
+        /// </para>
+        /// </remarks>
+        private bool IsMessageAboutTheSameModelType(string exceptionMessage)
+        {
+            var matches = GetPublishedModelsTypesRegex.Matches(exceptionMessage);
+
+            if (matches.Count >= 2)
+            {
+                return string.Equals(matches[0].Value, matches[1].Value, StringComparison.InvariantCulture);
+            }
+
+            return false;
+        }
     }
 }


U4-8448 Background task runner missing a null check during shutdown

--- src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs
+++ src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs
@@ -305,7 +305,9 @@

             // tasks in the queue will be executed...
             if (wait == false) return;
-            _runningTask.Wait(); // wait for whatever is running to end...
+
+            if (_runningTask != null)
+                _runningTask.Wait(); // wait for whatever is running to end...
         }

         /// <summary>


Orders the grouped trees by name (which means the custom trees will be last now) Displays custom third party group - only if we have items to show in that group

--- src/Umbraco.Web/Trees/ApplicationTreeController.cs
+++ src/Umbraco.Web/Trees/ApplicationTreeController.cs
@@ -27,7 +27,6 @@
                 Current.Services.ApplicationTreeService.GetAllTypes()
                 .Select(x => (TreeType: x, TreeGroup: x.GetCustomAttribute<CoreTreeAttribute>(false)?.TreeGroup))
                 .GroupBy(x => x.TreeGroup)
-                .OrderByDescending(x => x.Key)
                 .ToList());

@@ -135,13 +134,16 @@
                     treeGroupName = "thirdPartyGroup";
                 }

-                var groupRoot = SectionRootNode.CreateMultiTreeSectionRoot(rootId, groupNodeCollection);
-                groupRoot.Name = Services.TextService.Localize("treeHeaders/" + treeGroupName);
-
-                rootNodeGroups.Add(groupRoot);
-            }
-
-            return rootNodeGroups;
+                if (groupNodeCollection.Any())
+                {
+                    var groupRoot = SectionRootNode.CreateMultiTreeSectionRoot(rootId, groupNodeCollection);
+                    groupRoot.Name = Services.TextService.Localize("treeHeaders/" + treeGroupName);
+
+                    rootNodeGroups.Add(groupRoot);
+                }
+            }
+
+            return rootNodeGroups.OrderBy(x => x.Name);
         }

         /// <summary>


WWT.Providers: MarsDEMProvider: simplify, given the reality that the chunk files are gone

--- src/WWT.Providers/TileProviders/MarsDEMProvider.cs
+++ src/WWT.Providers/TileProviders/MarsDEMProvider.cs
@@ -25,27 +25,12 @@
             if (errored)
                 return;

+            // These files seem to have been lost. Azure behavior is to return all zeros.
+            //string filename = $@"{_options.WWTDEMDir}\toast\mars\Chunks\{level}\{tileY}.chunk";
+
             int demSize = 513 * 2;
-
-            string filename = $@"{_options.WWTDEMDir}\toast\mars\Chunks\{level}\{tileY}.chunk";
-
-            if (File.Exists(filename))
-            {
-                byte[] data = new byte[demSize];
-                FileStream fs = File.OpenRead(filename);
-                fs.Seek((long)(demSize * tileX), SeekOrigin.Begin);
-
-                fs.Read(data, 0, demSize);
-                fs.Close();
-                await context.Response.OutputStream.WriteAsync(data, 0, demSize, token);
-            }
-            else
-            {
-                byte[] data = new byte[demSize];
-
-                await context.Response.OutputStream.WriteAsync(data, 0, demSize, token);
-            }
-
+            byte[] data = new byte[demSize];
+            await context.Response.OutputStream.WriteAsync(data, 0, demSize, token);
             context.Response.End();
         }
     }


Introducing a compilation bug to fail a buil in VSMC

--- FacesToSmileys/ViewModels/TakePhotoViewModel.cs
+++ FacesToSmileys/ViewModels/TakePhotoViewModel.cs
@@ -75,7 +75,7 @@
         private void TakeActionForAPhoto(byte[] photo)
         {
             // First look at the size of the photo
-            var size = photo.Length;
+            var size = photo.Length
         }
     }
 }


RAM-#1880: Display address of OSM import

modified:   Nucleus/Nucleus.Maps/MapExtractor.cs

--- Nucleus/Nucleus.Maps/MapExtractor.cs
+++ Nucleus/Nucleus.Maps/MapExtractor.cs
@@ -151,6 +151,8 @@
             var place = xmlTree.Element("place");
             string lat = place.Attribute("lat").Value;
             string lon = place.Attribute("lon").Value;
+            var displayName = place.Attribute("display_name").Value;
+            log?.RaiseAlert($"Found data: {displayName}");

             double latitude;
             double.TryParse(lat, NumberStyles.Any, CultureInfo.InvariantCulture, out latitude);


リファクタリング

リファクタリング

--- LinqToDejizo/DejizoProvider.cs
+++ LinqToDejizo/DejizoProvider.cs
@@ -35,7 +35,7 @@

         public override object Execute(Expression expression)
         {
-            SearchDicItemCondition condition = new SearchDicItemCondition();
+            var condition = new SearchDicItemCondition();

             ParseLinqRoot(expression, condition);

@@ -118,9 +118,11 @@
             var count =
                 _((IQueryable<object> c) => c.Count(),
                     arguments: new[] { query });
+
             var first =
                 _((IQueryable<object> c) => c.First(),
                     arguments: new[] { query });
+
             var single =
                 _((IQueryable<object> c) => c.Single(),
                     arguments: new[] { query });
@@ -156,19 +158,6 @@
             wholeExtention.Parse(expression);
         }

-
-
-
-
-
-
-
-
-
-
-
-
-
         public override string GetQueryText(Expression expression)
         {
             return "query text";


version 1.1.0

version 1.1.0

--- common/GlobalAssemblyInfo.cs
+++ common/GlobalAssemblyInfo.cs
@@ -9,5 +9,5 @@

 [assembly: ComVisible(false)]

-[assembly: AssemblyVersion("1.0.0")]
-[assembly: AssemblyFileVersion("1.0.0")]
+[assembly: AssemblyVersion("1.1.0")]
+[assembly: AssemblyFileVersion("1.1.0")]


BUILD: New version of WindowsAzure.StorageExtensions

--- src/WindowsAzure/Properties/VersionAssemblyInfo.cs
+++ src/WindowsAzure/Properties/VersionAssemblyInfo.cs
@@ -1,5 +1,5 @@
 using System.Reflection;

-[assembly: AssemblyVersion("0.8.119")]
-[assembly: AssemblyFileVersion("0.8.119")]
-[assembly: AssemblyInformationalVersion("0.8.119")]
+[assembly: AssemblyVersion("0.8.122")]
+[assembly: AssemblyFileVersion("0.8.122")]
+[assembly: AssemblyInformationalVersion("0.8.122")]


Stop the Spongemock command from doubling digits.

--- FruitBowlBot/Commands/SpongebobPluginCommand.cs
+++ FruitBowlBot/Commands/SpongebobPluginCommand.cs
@@ -95,7 +95,7 @@
                 for (int i = 0; i < input.Length; i++)
                 {
                     int r = rng.Next(1, 3);
-                    if (i != 0)
+                    if (i != 0 && input[i].IsDigit() == false)
                     {
                         if (input[i] == char.ToUpper(input[i]))
                             temp += char.ToLower(input[i]);
@@ -117,7 +117,7 @@
                 for (int i = 0; i < input.Length; i++)
                 {
                     int r = rng.Next(1, 3);
-                    if (i != 0)
+                    if (i != 0 && input[i].IsDigit() == false)
                     {
                         if (input[i] == char.ToUpper(input[i]))
                             temp += char.ToLower(input[i]);


Tweak ObservableTraceListener.

Tweak ObservableTraceListener.

--- Gu.Wpf.FlipView.Demo/ObservableTraceListener.cs
+++ Gu.Wpf.FlipView.Demo/ObservableTraceListener.cs
@@ -2,14 +2,16 @@
 {
     using System.Collections.ObjectModel;
     using System.Diagnostics;
+    using System.Text;

     public class ObservableTraceListener : System.Diagnostics.TraceListener
     {
         public static readonly ObservableTraceListener Instance = new ObservableTraceListener();

+        private readonly StringBuilder StringBuilder = new StringBuilder();
+
         private ObservableTraceListener()
         {
-            PresentationTraceSources.Refresh();
             Register(PresentationTraceSources.AnimationSource);
             Register(PresentationTraceSources.DataBindingSource);
             Register(PresentationTraceSources.DocumentsSource);
@@ -38,11 +40,14 @@

         public override void Write(string message)
         {
+            this.StringBuilder.Append(message);
         }

         public override void WriteLine(string message)
         {
-            this.Messages.Add(message);
+            this.StringBuilder.Append(message);
+            this.Messages.Add(this.StringBuilder.ToString());
+            this.StringBuilder.Clear();
         }
     }
 }


Resize screen when it shows

Resize screen when it shows

--- MonoHaven.Client/MainWindow.cs
+++ MonoHaven.Client/MainWindow.cs
@@ -49,6 +49,7 @@
 			currentScreen.Close();
 			currentScreen = screen ?? EmptyScreen.Instance;
 			inputListener = currentScreen;
+			currentScreen.Resize(Width, Height);
 			currentScreen.Show();
 		}


Fix ordered await bug; closes #49

Fix ordered await bug; closes #49

There were two nasty bugs. First, there was a problem with capture of a
modified closure in a for-loop that caused the ordering keys to be
garbage. Second, an exit condition was missing when looping and
releasing withheld results.

--- MoreLinq/Experimental/Await.cs
+++ MoreLinq/Experimental/Await.cs
@@ -405,11 +405,11 @@
                                 for (nextKey++; holds.Count > 0; nextKey++)
                                 {
                                     var (candidateKey, candidate) = holds[0];
-                                    if (candidateKey == nextKey)
-                                    {
-                                        releaseCount++;
-                                        yield return candidate;
-                                    }
+                                    if (candidateKey != nextKey)
+                                        break;
+
+                                    releaseCount++;
+                                    yield return candidate;
                                 }

                                 holds.RemoveRange(0, releaseCount);
@@ -477,12 +477,14 @@

                 var tasks = new List<Task<(T, TResult)>>();

-                var more = false;
-                for (var i = 0; i < maxConcurrency && (more = e.MoveNext()); i++)
-                    tasks.Add(taskSelector(e.Current).Select(r => (e.Current, r)));
-
-                if (!more)
-                    e.Dispose();
+                var reader = new Reader<T>(e);
+
+                for (var i = 0; i < maxConcurrency; i++)
+                {
+                    if (!reader.TryRead(out var item))
+                        break;
+                    tasks.Add(taskSelector(item).Select(r => (item, r)));
+                }

                 try
                 {
@@ -517,13 +519,8 @@
                         tasks.Remove(task);
                         collection.Add(resultNoticeSelector(task.Result.Input, task.Result.Result));

-                        if (more)
-                        {
-                            if (more = e.MoveNext())
-                                tasks.Add(taskSelector(e.Current).Select(r => (e.Current, r)));
-                            else
-                                e.Dispose();
-                        }
+                        if (reader.TryRead(out var item))
+                            tasks.Add(taskSelector(item).Select(r => (item, r)));
                     }

                     collection.Add(endNotice);
@@ -538,6 +535,30 @@
             }
         }

+        sealed class Reader<T>
+        {
+            IEnumerator<T> _enumerator;
+
+            public Reader(IEnumerator<T> enumerator) =>
+                _enumerator = enumerator;
+
+            public bool TryRead(out T item)
+            {
+                var e = _enumerator;
+
+                if (e == null || !e.MoveNext())
+                {
+                    _enumerator = null;
+                    e?.Dispose();
+                    item = default;
+                    return false;
+                }
+
+                item = e.Current;
+                return true;
+            }
+        }
+
         static class AwaitQuery
         {
             public static IAwaitQuery<T>


日常修正+链表有序集合规划

日常修正+链表有序集合规划

--- MyGeneric/MyGeneric/Program.cs
+++ MyGeneric/MyGeneric/Program.cs
@@ -8,8 +8,8 @@
     {
         static int Main()
         {
-            MyStack<int> a = new MyStack<int>(8 * 1024);
-            MySortedList<int> b = new MySortedList<int>();
+            MyStack<int> a = new MyStack<int>();
+            MySortedSet<int> b = new MySortedSet<int>();
             a.Push(1);
             a.Push(2);
             a.Push(1);
@@ -37,8 +37,8 @@
     {
         readonly T[] _stack;
         int _top = -1;
-        bool IsFull => _top == Capacity - 1;
-        bool IsEmpty => _top < 0;
+        bool _IsFull => _top == Capacity - 1;
+        bool _IsEmpty => _top < 0;

         public MyStack(int capacity = 256)
         {
@@ -60,7 +60,7 @@

         public T Peek()
         {
-            if (IsEmpty)
+            if (_IsEmpty)
                 throw new InvalidOperationException("栈为空！");

             return _stack[_top];
@@ -68,7 +68,7 @@

         public T Pop()
         {
-            if (IsEmpty)
+            if (_IsEmpty)
                 throw new InvalidOperationException("栈为空！");

             return _stack[_top--];
@@ -76,7 +76,7 @@

         public void Push(T e)
         {
-            if (IsFull)
+            if (_IsFull)
                 throw new StackOverflowException("栈已满！");

             _stack[++_top] = e;
@@ -84,80 +84,55 @@

     }

-    class MySortedList<T> : IEnumerable<T>, IReadOnlyList<T> where T : IComparable<T>
+    class MyList<T> : IEnumerable<T>, IReadOnlyList<T>
     {
         T[] _myList = new T[0]; // 数组使用时新建一个，不是创建对象时建立capacity大小的数组

-        public MySortedList(int capacity = 256)
+        public MyList(int capacity = 256)
         {
             if (capacity < 0)
-                throw new ArgumentOutOfRangeException(nameof(capacity), "列表大小不能为负！");
+                throw new ArgumentOutOfRangeException(nameof(capacity), "列表长度不能为负！");
             if (capacity > 512)
-                throw new ArgumentOutOfRangeException(nameof(capacity), "申请的列表太大！");
+                throw new ArgumentOutOfRangeException(nameof(capacity), "申请的列表太长！");

             Capacity = capacity;
         }

-        public void Clear() => _myList = new T[0];
-
-
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            for (int i = 0; i < Count; i++)
-                yield return _myList[i];
-        }
-        IEnumerator<T> IEnumerable<T>.GetEnumerator()
-        {
-            for (int i = 0; i < Count; i++)
-                yield return _myList[i];
-        }
-
-        public int Count => _myList.Length;
+        public int Count { get; private set; }
         public int Capacity { get; }
         public T this[int index] => _myList[index];

-        public bool Contains(T item)
-        {
-            foreach (T e in _myList)
-                if (e.Equals(item))
-                    return true;
-            return false;
-        }
+        public IEnumerator<T> GetEnumerator() => _myList.GetEnumerator() as IEnumerator<T>;
+        IEnumerator IEnumerable.GetEnumerator() => _myList.GetEnumerator();
+
+        public void Clear() => _myList = new T[0];

         public bool Add(T item)
         {
+            T[] tempList = _myList;
+
             if (Count == Capacity)
                 throw new InvalidOperationException("列表已满！");

-            T[] tempSet = new T[Count + 1];
-            tempSet[Count] = item; // 直接把元素添加到最后一个
-            for (int i = 0, j = 0; i < Count - 1; i++)
-            {
-                if (item.CompareTo(_myList[i]) < 0)
-                {
-                    tempSet[i] = item;
-                    j = 1; //成功插入后，数组复制的下标相差1
-                }
-                tempSet[i + j] = _myList[i]; //如已成功插入，则会覆盖刚才添加到最后的e
-            }
-            _myList = tempSet;
+            if (Contains(item))
+                return false;
+
+            if (Count == _myList.Length)
+                tempList = new T[Count + 4];
+
+            tempList[Count++] = item;
             return true;
         }

-        public bool AddRange(T[] collection)
+        public void AddRange(T[] collection)
         {
             foreach (var e in collection)
-                if (!Add(e))
-                    return false;
-            return true;
+                Add(e);
         }

         public bool Remove(T item)
         {
-            if (item == null)
-                return true;
-            if (Count == 0)
-                throw new InvalidOperationException("集合为空！");
+            T[] tempList = new T[Count - 1];

             int itemi = -1;
             for (int i = 0; i < Count - 1; i++)
@@ -165,15 +140,103 @@
             if (itemi == -1)
                 return false;

-            T[] tempSet = new T[Count - 1];
             for (int i = 0, j = 0; i < Count - 1; i++)
             {
                 if (i == itemi)
                     j = 1;
-                tempSet[i] = _myList[i + j];
+                tempList[i] = _myList[i + j];
             }
-            _myList = tempSet;
+            _myList = tempList;
             return true;
         }
-    }
-}+
+        public bool Contains(T item)
+        {
+            foreach (T e in _myList)
+                if (e.Equals(item))
+                    return true;
+            return false;
+        }
+    }
+
+    class MySortedSet<T> : IEnumerable<T>, IReadOnlyCollection<T> where T : IComparable<T>
+    {
+        Node _head;
+
+        class Node
+        {
+            public T data;
+            public Node next;
+
+            internal Node() : this(default(T), null) { }
+            internal Node(T data) : this(data, null) { }
+            internal Node(Node next) : this(default(T), next) { }
+            internal Node(T data, Node next)
+            {
+                this.data = data;
+                this.next = next;
+            }
+        }
+
+        public MySortedSet() => _head = new Node();
+
+        public int Count => throw new NotImplementedException();
+        public T Max => throw new NotImplementedException();
+        public T Min => throw new NotImplementedException();
+        public T this[int index] => throw new NotImplementedException();
+        public void Clear() => _head.next = null;
+
+        public IEnumerator<T> GetEnumerator()
+        {
+            throw new NotImplementedException();
+        }
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            throw new NotImplementedException();
+        }
+
+        public bool Add(T item)
+        {
+            throw new NotImplementedException();
+
+        }
+
+        public bool Contains(T item)
+        {
+            throw new NotImplementedException();
+        }
+
+        public bool Remove(T item)
+        {
+            throw new NotImplementedException();
+        }
+
+        public bool Reverse(T item)
+        {
+            throw new NotImplementedException();
+        }
+
+        /*
+         * 使用数组储存有序集合时的Add方法
+        public bool Add(T item)
+        {
+            if (Count == Capacity)
+                throw new InvalidOperationException("集合已满！");
+
+            T[] tempSet = new T[Count + 1];
+            tempSet[Count] = item; // 直接把元素添加到最后一个
+            for (int i = 0, j = 0; i < Count - 1; i++)
+            {
+                if (item.CompareTo(_mySet[i]) < 0)
+                {
+                    tempSet[i] = item;
+                    j = 1; //成功插入后，数组复制的下标相差1
+                }
+                tempSet[i + j] = _mySet[i]; //如已成功插入，则会覆盖刚才添加到最后的e
+            }
+            _mySet = tempSet;
+            return true;
+        }
+        */
+    }
+}


Native example now works flawless - hurray

--- NetInject.Cecil/TypePatcher.cs
+++ NetInject.Cecil/TypePatcher.cs
@@ -144,10 +144,16 @@
             TypeReference returnType;
             var methDef = meth as MethodDefinition ?? meth.TryResolve();
             var genRef = meth as GenericInstanceMethod;
-            if (TryGetValue(body.Method, methDef.DeclaringType, out declaringType))
-                onReplace(methDef.DeclaringType);
-            if (TryGetValue(body.Method, methDef.ReturnType, out returnType))
-                onReplace(methDef.ReturnType);
+            var methDeclType = meth.DeclaringType.IsGenericInstance
+                ? meth.DeclaringType
+                : methDef?.DeclaringType ?? meth.DeclaringType;
+            var methRetType = meth.ReturnType.IsGenericInstance
+                ? meth.ReturnType
+                : methDef?.ReturnType ?? meth.ReturnType;
+            if (TryGetValue(body.Method, methDeclType, out declaringType))
+                onReplace(methDeclType);
+            if (TryGetValue(body.Method, methRetType, out returnType))
+                onReplace(methRetType);
             TypeReference tempType;
             var genArgs = new TypeReference[0];
             if (genRef != null && (genArgs = genRef.GenericArguments.Select(


IpRouteController should be using the ip-route util

--- IPTables.Net/IpUtils/Utils/IpRouteController.cs
+++ IPTables.Net/IpUtils/Utils/IpRouteController.cs
@@ -6,7 +6,7 @@
 {
     public class IpRouteController : IpController
     {
-        public IpRouteController(ISystemFactory system) : base("rule", system)
+        public IpRouteController(ISystemFactory system) : base("route", system)
         {
         }