Minor gif fix

Minor gif fix

--- source/FFImageLoading.Droid/Views/ManagedImageView.cs
+++ source/FFImageLoading.Droid/Views/ManagedImageView.cs
@@ -138,8 +138,6 @@
                 ImageService.Instance.CancelWorkFor(ImageLoaderTask);
                 ImageLoaderTask = null;
             }
-
-            CancelGifPlay();
         }

 		public override void SetImageDrawable(Drawable drawable)


Fix test

Fix test

--- Refit.Tests/InterfaceStubGenerator.cs
+++ Refit.Tests/InterfaceStubGenerator.cs
@@ -139,7 +139,7 @@
                 .ToList();

             var result = fixture.GenerateTemplateInfoForInterfaceList(input);
-            Assert.Equal(5, result.ClassList.Count);
+            Assert.Equal(6, result.ClassList.Count);

             var inherited = result.ClassList.First(c => c.InterfaceName == "IAmInterfaceC");


Fixed line-feeds added in last commit

Fixed line-feeds added in last commit

--- OpenMetaverse/Settings.cs
+++ OpenMetaverse/Settings.cs
@@ -138,27 +138,27 @@
         /// Network stats queue length (seconds)
         public int STATS_QUEUE_SIZE = 5;

-        #endregion
-
-        #region Experimental options
-
-        ///
-        /// Primitives will be reused when falling in/out of interest list (and shared between clients)
-        ///  prims returning to interest list do not need re-requested
-        ///  Helps also in not re-requesting prim.Properties for code that checks for a Properties == null per client
-        ///
-        public bool CACHE_PRIMITIVES = false;
-        ///
-        /// Pool parcel data between clients (saves on requesting multiple times when all clients may need it)
-        ///
-        public bool POOL_PARCEL_DATA = false;
-        ///
-        /// How long to preserve cached data when no client is connected to a simulator
-        ///   The reason for setting it to something like 2 minutes is in case a client
-        ///    is running back and forth between region edges or a sim is comming and going
-        ///
-        public static int SIMULATOR_POOL_TIMEOUT = 2 * 60 * 1000;
-
+        #endregion
+
+        #region Experimental options
+
+        ///
+        /// Primitives will be reused when falling in/out of interest list (and shared between clients)
+        ///  prims returning to interest list do not need re-requested
+        ///  Helps also in not re-requesting prim.Properties for code that checks for a Properties == null per client
+        ///
+        public bool CACHE_PRIMITIVES = false;
+        ///
+        /// Pool parcel data between clients (saves on requesting multiple times when all clients may need it)
+        ///
+        public bool POOL_PARCEL_DATA = false;
+        ///
+        /// How long to preserve cached data when no client is connected to a simulator
+        ///   The reason for setting it to something like 2 minutes is in case a client
+        ///    is running back and forth between region edges or a sim is comming and going
+        ///
+        public static int SIMULATOR_POOL_TIMEOUT = 2 * 60 * 1000;
+
         #endregion

         #region Configuration options (mostly booleans)
@@ -346,7 +346,7 @@
         #region Private Fields

         private GridClient Client;
-        private int priceUpload = 0;
+        private int priceUpload = 0;
         public static bool SORT_INVENTORY = false;

         /// Constructor


Empty strings need to be quoted in IMAP commands (such as SEARCH)

--- MailKit/Net/Imap/ImapCommand.cs
+++ MailKit/Net/Imap/ImapCommand.cs
@@ -373,6 +373,9 @@
 		{
 			var type = ImapStringType.Atom;

+			if (value.Length == 0)
+				return ImapStringType.QString;
+
 			for (int i = 0; i < value.Length; i++) {
 				if (!IsAtom (value[i])) {
 					if (!IsQuotedSafe (value[i]))


trellofactory.me should refresh me since it's awaiting anyway

--- Manatee.Trello/TrelloFactory.cs
+++ Manatee.Trello/TrelloFactory.cs
@@ -86,7 +86,11 @@
 		public async Task<IMe> Me(CancellationToken ct = default(CancellationToken))
 		{
 			var id = await Trello.Me.GetId(ct);
-			return TrelloConfiguration.Cache.Find<Me>(id) ?? new Me(id);
+			var me = TrelloConfiguration.Cache.Find<Me>(id) ?? new Me(id);
+
+			await me.Refresh(false, ct);
+
+			return me;
 		}

 		/// <summary>


reload texts in options window upon changing language

--- src/FormOptions.cs
+++ src/FormOptions.cs
@@ -18,6 +18,7 @@
 		PictureBox[] pboxPens = new PictureBox[10];
 		ComboBox[] comboPensAlpha = new ComboBox[10];
 		ComboBox[] comboPensWidth = new ComboBox[10];
+		Label lbcbPens, lbpboxPens, lbcomboPensAlpha, lbcomboPensWidth;

 		Label[] lbHotkeyPens = new Label[10];
 		HotkeyInputBox[] hiPens = new HotkeyInputBox[10];
@@ -62,29 +63,29 @@

 			lbNote.ForeColor = Color.Black;

-			Label lbcbPens = new Label();
+			lbcbPens = new Label();
 			lbcbPens.Left = 90;
 			lbcbPens.Width = 35;
 			lbcbPens.Top = 15;
-			lbcbPens.Text = Root.Local.OptionsPensShow;
+
 			tabPage2.Controls.Add(lbcbPens);
-			Label lbpboxPens = new Label();
+			lbpboxPens = new Label();
 			lbpboxPens.Left = 125;
 			lbpboxPens.Width = 35;
 			lbpboxPens.Top = 15;
-			lbpboxPens.Text = Root.Local.OptionsPensColor;
+
 			tabPage2.Controls.Add(lbpboxPens);
-			Label lbcomboPensAlpha = new Label();
+			lbcomboPensAlpha = new Label();
 			lbcomboPensAlpha.Left = 160;
 			lbcomboPensAlpha.Width = 55;
 			lbcomboPensAlpha.Top = 15;
-			lbcomboPensAlpha.Text = Root.Local.OptionsPensAlpha;
+
 			tabPage2.Controls.Add(lbcomboPensAlpha);
-			Label lbcomboPensWidth = new Label();
+			lbcomboPensWidth = new Label();
 			lbcomboPensWidth.Left = 250;
 			lbcomboPensWidth.Width = 55;
 			lbcomboPensWidth.Top = 15;
-			lbcomboPensWidth.Text = Root.Local.OptionsPensWidth;
+
 			tabPage2.Controls.Add(lbcomboPensWidth);

 			for (int p = 0; p < Root.MaxPenCount; p++)
@@ -94,7 +95,6 @@
 				lbPens[p].Left = 40;
 				lbPens[p].Width = 40;
 				lbPens[p].Top = top;
-				lbPens[p].Text = Root.Local.ButtonNamePen[p];

 				cbPens[p] = new CheckBox();
 				cbPens[p].Left = 90;
@@ -113,7 +113,7 @@
 				pboxPens[p].Click += pboxPens_Click;

 				comboPensAlpha[p] = new ComboBox();
-				comboPensAlpha[p].Items.AddRange(new object[] { Root.Local.OptionsPensPencil, Root.Local.OptionsPensHighlighter });
+
 				comboPensAlpha[p].Left = 160;
 				comboPensAlpha[p].Top = top - 2;
 				comboPensAlpha[p].Width = 70;
@@ -121,7 +121,7 @@
 				comboPensAlpha[p].TextChanged += comboPensAlpha_TextChanged;

 				comboPensWidth[p] = new ComboBox();
-				comboPensWidth[p].Items.AddRange(new object[] {Root.Local.OptionsPensThin, Root.Local.OptionsPensNormal, Root.Local.OptionsPensThick});
+
 				comboPensWidth[p].Left = 250;
 				comboPensWidth[p].Top = top - 2;
 				comboPensWidth[p].Width = 70;
@@ -142,7 +142,6 @@
 				lbHotkeyPens[p].Left = 20;
 				lbHotkeyPens[p].Width = 40;
 				lbHotkeyPens[p].Top = top;
-				lbHotkeyPens[p].Text = Root.Local.ButtonNamePen[p];

 				hiPens[p] = new HotkeyInputBox();
 				hiPens[p].Hotkey = Root.Hotkey_Pens[p];
@@ -165,6 +164,11 @@
 			hiRedo.Hotkey = Root.Hotkey_Redo;
 			hiClear.Hotkey = Root.Hotkey_Clear;

+			FormOptions_LocalReload();
+		}
+
+		private void FormOptions_LocalReload()
+		{
 			this.Text = Root.Local.MenuEntryOptions + " - gInk";
 			tabControl1.TabPages[0].Text = Root.Local.OptionsTabGeneral;
 			tabControl1.TabPages[1].Text = Root.Local.OptionsTabPens;
@@ -189,11 +193,30 @@
 			this.comboCanvasCursor.Items[0] = Root.Local.OptionsGeneralCanvascursorArrow;
 			this.comboCanvasCursor.Items[1] = Root.Local.OptionsGeneralCanvascursorPentip;

+
+			for (int p = 0; p < Root.MaxPenCount; p++)
+			{
+				comboPensAlpha[p].Items.Clear();
+				comboPensWidth[p].Items.Clear();
+				comboPensAlpha[p].Items.AddRange(new object[] { Root.Local.OptionsPensPencil, Root.Local.OptionsPensHighlighter });
+				comboPensWidth[p].Items.AddRange(new object[] { Root.Local.OptionsPensThin, Root.Local.OptionsPensNormal, Root.Local.OptionsPensThick });
+
+				lbPens[p].Text = Root.Local.ButtonNamePen[p];
+				lbHotkeyPens[p].Text = Root.Local.ButtonNamePen[p];
+
+				lbcbPens.Text = Root.Local.OptionsPensShow;
+				lbpboxPens.Text = Root.Local.OptionsPensColor;
+				lbcomboPensAlpha.Text = Root.Local.OptionsPensAlpha;
+				lbcomboPensWidth.Text = Root.Local.OptionsPensWidth;
+			}
+
+				comboLanguage.Items.Clear();
 			List<string> langs = Root.Local.GetLanguagenames();
 			foreach (string languagename in langs)
 			{
 				comboLanguage.Items.Add(languagename);
 			}
+
 			string ln = Root.Local.GetLanguagenameByFilename(Root.Local.CurrentLanguageFile);
 			if (comboLanguage.Items.Contains(ln))
 				comboLanguage.SelectedIndex = comboLanguage.Items.IndexOf(ln);
@@ -402,7 +425,11 @@

 		private void comboLanguage_SelectedIndexChanged(object sender, EventArgs e)
 		{
-			Root.Local.LoadLocalFile(Root.Local.GetFilenameByLanguagename(comboLanguage.Text));
+			if (comboLanguage.Text != Root.Local.GetLanguagenameByFilename(Root.Local.CurrentLanguageFile))
+			{
+				Root.Local.LoadLocalFile(Root.Local.GetFilenameByLanguagename(comboLanguage.Text));
+				FormOptions_LocalReload();
+			}
 		}
 	}
 }


Sets script output to debug if built in debug configuration.

This is the exact same change recently made on WebForms EE.

Useful for users building the examples from sources and testing at their
development environment.

--- src/Global.asax.cs
+++ src/Global.asax.cs
@@ -85,5 +85,21 @@
                 Ext.Net.ResourceManager.AddFactoryView("~/Areas/Miscellaneous_Factory/Views/Basic/MyWindow2.cshtml", "mywindow2", "My.Window2");
             }
         }
+
+        protected void Session_Start(object sender, EventArgs e)
+        {
+#if DEBUG
+            // Enables debugging code output by default if the project is built in debug configuration.
+            if (Session["Ext.Net.ScriptMode"] == null)
+            {
+                Session["Ext.Net.ScriptMode"] = ScriptMode.Debug;
+            }
+
+            if (Session["Ext.Net.SourceFormatting"] == null)
+            {
+                Session["Ext.Net.SourceFormatting"] = true;
+            }
+#endif // DEBUG
+        }
     }
 }


Increase console buffer.

Increase console buffer.

--- EarthWithMagic/Program.cs
+++ EarthWithMagic/Program.cs
@@ -14,6 +14,7 @@
         private static void Main(string[] args)
         {
             Console.OutputEncoding = System.Text.Encoding.Unicode;
+            Console.SetBufferSize(Console.BufferWidth, 32766);
             Util.WriteLine(ResourceGM.GetResource("EarthMagicDocumentation.ASCII_Art.Title.txt"));
             //Util.WriteLine(ResourceGM.GetResource("EarthMagicDocumentation.ASCII_Art.Dragon_Breathing_Fire.txt"));


Updated CJK unicode intervals

Updated CJK unicode intervals

--- EditedTokenLocator/Cjk.cs
+++ EditedTokenLocator/Cjk.cs
@@ -30,34 +30,40 @@
 		/// <summary>
 		/// Диапазоны иероглифов.
 		/// Аббревиатура CJK в названии расшифровывается как chinese japanese korean.
-		/// https://docs.microsoft.com/en-us/dotnet/standard/base-types/character-classes-in-regular-expressions
+		/// https://en.wikipedia.org/wiki/Unicode_block
 		///
 		/// Диапазоны упорядочены по-возрастанию для оптимизации поиска
 		/// </summary>
 		private static readonly List<CharRange> CjkCharacterRanges = new List<CharRange>
 		{
-			new CharRange('\u1100', '\u11FF'), // IsHangulJamo
-			new CharRange('\u2E80', '\u2EFF'), // IsCJKRadicalsSupplement
+			new CharRange('\u1100', '\u11FF'), // Hangul Jamo
+			new CharRange('\u2E80', '\u2EFF'), // CJK Radicals Supplement

-			// new CharRange('\u3000', '\u303F'), // IsCJKSymbolsandPunctuation
+			// new CharRange('\u3000', '\u303F'), // CJK Symbols and Punctuation
 			// new CharRange('\u3040', '\u309F'), // Hiragana
 			// new CharRange('\u30A0', '\u30FF'), // Katakana
 			// new CharRange('\u3100', '\u312F'), // Bopomofo
 			// new CharRange('\u3130', '\u318F'), // Hangul Compatibility Jamo
 			// new CharRange('\u3190', '\u319F'), // Kanbun
 			// new CharRange('\u31A0', '\u31BF'), // Bopomofo Extended
-			new CharRange('\u3000', '\u31BF'), // слиты 7 подряд идущих диапазона выше
+			// new CharRange('\u31C0', '\u31EF'), // CJK Strokes
+			// new CharRange('\u31F0', '\u31FF'), // Katakana Phonetic Extensions
+			// new CharRange('\u3200', '\u32FF'), // Enclosed CJK Letters and Months
+			// new CharRange('\u3300', '\u33FF'), // CJK Compatibility
+			// new CharRange('\u3400', '\u4DBF'), // CJK Unified Ideographs ExtensionA
+			// new CharRange('\u4DC0', '\u4DFF'), // Yijing Hexagram Symbols
+			// new CharRange('\u4E00', '\u9FFF'), // CJK Unified Ideographs
+			new CharRange('\u3000', '\u9FFF'), // слиты 14 подряд идущих диапазонов выше
+
+			new CharRange('\uA960', '\uA97F'), // Hangul Jamo Extended-A

-			//new CharRange('\u31F0', '\u31FF'), // Katakana Phonetic Extensions
-			//new CharRange('\u3200', '\u32FF'), // IsEnclosedCJKLettersandMonths
-			//new CharRange('\u3300', '\u33FF'), // IsCJKCompatibility
-			//new CharRange('\u3400', '\u4DBF'), // IsCJKUnifiedIdeographsExtensionA
-			new CharRange('\u31F0', '\u4DBF'), // слиты 4 подряд идущих диапазона выше
+			// new CharRange('\uAC00', '\uD7AF'), // Hangul Syllables
+			// new CharRange('\uD7B0', '\uD7FF'), // Hangul Jamo Extended-B
+			new CharRange('\uAC00', '\uD7FF'), // слиты 2 подряд идущих диапазона выше

-			new CharRange('\u4E00', '\u9FFF'), // IsCJKUnifiedIdeographs
-			new CharRange('\uAC00', '\uD7AF'), // IsHangulSyllables
-			new CharRange('\uF900', '\uFAFF'), // IsCJKCompatibilityIdeographs
-			new CharRange('\uFE30', '\uFE4F'), // IsCJKCompatibilityForms
+
+			new CharRange('\uF900', '\uFAFF'), // CJK Compatibility Ideographs
+			new CharRange('\uFE30', '\uFE4F'), // CJK Compatibility Forms
 			new CharRange('\uFF00', '\uFFEF') // Halfwidth and Fullwidth Forms
 		};


менюта

менюта

--- Game/StopTheBunny/Logo.cs
+++ Game/StopTheBunny/Logo.cs
@@ -1,11 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace StopTheBunny
+namespace StopTheBunny
 {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Text;
+    using System.Threading.Tasks;
+
     public static class Logo
     {
         private static int sizeMatrix = 21;


#759. Поправлена проверка заполняемости свойств

--- src/ScriptEngine.HostedScript/Library/SystemGlobalContext.cs
+++ src/ScriptEngine.HostedScript/Library/SystemGlobalContext.cs
@@ -545,7 +545,7 @@
                     var propIdx = acceptor.FindProperty(srcProperty);
                     var srcPropIdx = source.FindProperty(srcProperty);

-                    if(source.IsPropReadable(propIdx) && acceptor.IsPropWritable(propIdx))
+                    if(source.IsPropReadable(srcPropIdx) && acceptor.IsPropWritable(propIdx))
                         acceptor.SetPropValue(propIdx, source.GetPropValue(srcPropIdx));

                 }


V4.12.3

--- src/Senparc.Weixin/Senparc.Weixin/Properties/AssemblyInfo.cs
+++ src/Senparc.Weixin/Senparc.Weixin/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@
 // 可以指定所有这些值，也可以使用“生成号”和“修订号”的默认值，
 // 方法是按如下所示使用“*”:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("4.11.11.*")]
+[assembly: AssemblyVersion("4.12.3.*")]
 //[assembly: AssemblyFileVersion("1.0.0.0")]


Fix flaky HubConnectionHandler test (#18391)

--- src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs
+++ src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs
@@ -6,9 +6,11 @@
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
+using System.IO.Pipelines;
 using System.Linq;
 using System.Security.Claims;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
 using MessagePack;
 using MessagePack.Formatters;
@@ -2797,6 +2799,78 @@
             }
         }

+        internal class PipeReaderWrapper : PipeReader
+        {
+            private readonly PipeReader _originalPipeReader;
+            private TaskCompletionSource<object> _waitForRead;
+            private object _lock = new object();
+
+            public PipeReaderWrapper(PipeReader pipeReader)
+            {
+                _originalPipeReader = pipeReader;
+                _waitForRead = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
+            }
+
+            public override void AdvanceTo(SequencePosition consumed) =>
+                _originalPipeReader.AdvanceTo(consumed);
+
+            public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) =>
+                _originalPipeReader.AdvanceTo(consumed, examined);
+
+            public override void CancelPendingRead() =>
+                _originalPipeReader.CancelPendingRead();
+
+            public override void Complete(Exception exception = null) =>
+                _originalPipeReader.Complete(exception);
+
+            public override async ValueTask<ReadResult> ReadAsync(CancellationToken cancellationToken = default)
+            {
+                lock (_lock)
+                {
+                    _waitForRead.SetResult(null);
+                }
+
+                try
+                {
+                    return await _originalPipeReader.ReadAsync(cancellationToken);
+                }
+                finally
+                {
+                    lock (_lock)
+                    {
+                        _waitForRead = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
+                    }
+                }
+            }
+
+            public override bool TryRead(out ReadResult result) =>
+                _originalPipeReader.TryRead(out result);
+
+            public Task WaitForReadStart()
+            {
+                lock (_lock)
+                {
+                    return _waitForRead.Task;
+                }
+            }
+        }
+
+        internal class CustomDuplex : IDuplexPipe
+        {
+            private readonly IDuplexPipe _originalDuplexPipe;
+            public readonly PipeReaderWrapper WrappedPipeReader;
+
+            public CustomDuplex(IDuplexPipe duplexPipe)
+            {
+                _originalDuplexPipe = duplexPipe;
+                WrappedPipeReader = new PipeReaderWrapper(_originalDuplexPipe.Input);
+            }
+
+            public PipeReader Input => WrappedPipeReader;
+
+            public PipeWriter Output => _originalDuplexPipe.Output;
+        }
+
         [Fact]
         public async Task HubMethodInvokeDoesNotCountTowardsClientTimeout()
         {
@@ -2813,6 +2887,9 @@

                 using (var client = new TestClient(new JsonHubProtocol()))
                 {
+                    var customDuplex = new CustomDuplex(client.Connection.Transport);
+                    client.Connection.Transport = customDuplex;
+
                     var connectionHandlerTask = await client.ConnectAsync(connectionHandler);
                     // This starts the timeout logic
                     await client.SendHubMessageAsync(PingMessage.Instance);
@@ -2828,6 +2905,11 @@
                     tcsService.EndMethod.SetResult(null);

                     await hubMethodTask.OrTimeout();
+
+                    // There is a small window when the hub method finishes and the timer starts again
+                    // So we need to delay a little before ticking the heart beat.
+                    // We do this by waiting until we know the HubConnectionHandler code is in pipe.ReadAsync()
+                    await customDuplex.WrappedPipeReader.WaitForReadStart().OrTimeout();

                     // Tick heartbeat again now that we're outside of the hub method
                     client.TickHeartbeat();


extended timeout for tests

extended timeout for tests

--- source/ElasticsearchInside.Tests/ElasticsearchTests.cs
+++ source/ElasticsearchInside.Tests/ElasticsearchTests.cs
@@ -14,7 +14,7 @@
         [Test]
         public async Task Can_start()
         {
-            using (var elasticsearch = await new Elasticsearch(i => i.SetPort(4444).EnableLogging()).Ready())
+            using (var elasticsearch = await new Elasticsearch(i => i.SetPort(4444).EnableLogging().SetElasticsearchStartTimeout(60)).Ready())
             {
                 ////Arrange
                 var client = new ElasticClient(new ConnectionSettings(elasticsearch.Url));
@@ -31,7 +31,7 @@
         [Test]
         public void Can_start_sync()
         {
-            using (var elasticsearch = new Elasticsearch(i => i.SetPort(4444).EnableLogging()).ReadySync())
+            using (var elasticsearch = new Elasticsearch(i => i.SetPort(4444).EnableLogging().SetElasticsearchStartTimeout(60)).ReadySync())
             {
                 ////Arrange
                 var client = new ElasticClient(new ConnectionSettings(elasticsearch.Url));
@@ -46,7 +46,7 @@
         [Test]
         public async Task Can_insert_data()
         {
-            using (var elasticsearch = await new Elasticsearch(i => i.SetPort(4444).EnableLogging()).Ready())
+            using (var elasticsearch = await new Elasticsearch(i => i.SetPort(4444).EnableLogging().SetElasticsearchStartTimeout(60)).Ready())
             {
                 ////Arrange
                 var client = new ElasticClient(new ConnectionSettings(elasticsearch.Url));
@@ -64,7 +64,7 @@
         [Test]
         public async Task Can_change_configuration()
         {
-            using (var elasticsearch = await new Elasticsearch(c => c.SetPort(4444).EnableLogging().LogTo(Console.WriteLine).SetElasticsearchStartTimeout(10)).Ready())
+            using (var elasticsearch = await new Elasticsearch(c => c.SetPort(4444).EnableLogging().LogTo(Console.WriteLine).SetElasticsearchStartTimeout(60)).Ready())
             {
                 ////Arrange
                 var client = new ElasticClient(new ConnectionSettings(elasticsearch.Url));
@@ -82,7 +82,7 @@
         public async Task Can_log_output()
         {
             var logged = false;
-            using (var elasticsearch = new Elasticsearch(c => c.SetPort(4444).EnableLogging().LogTo(message => logged = true)))
+            using (var elasticsearch = new Elasticsearch(c => c.SetPort(4444).EnableLogging().LogTo(message => logged = true).SetElasticsearchStartTimeout(60)))
             {
                 await elasticsearch.Ready();

@@ -94,7 +94,7 @@
         [Test]
         public async Task Can_install_plugin()
         {
-            using (var elasticsearch = await new Elasticsearch(c => c.SetPort(4444).EnableLogging().AddPlugin(new Plugin("analysis-icu"))).Ready())
+            using (var elasticsearch = await new Elasticsearch(c => c.SetPort(4444).EnableLogging().AddPlugin(new Plugin("analysis-icu")).SetElasticsearchStartTimeout(60)).Ready())
             {
                 ////Arrange
                 var client = new ElasticClient(new ConnectionSettings(elasticsearch.Url));
@@ -114,7 +114,7 @@
             Settings settings;

             ////Act
-            using (var elasticsearch = await new Elasticsearch(c => c.SetPort(4444).EnableLogging().LogTo(Console.WriteLine)).Ready())
+            using (var elasticsearch = await new Elasticsearch(c => c.SetPort(4444).EnableLogging().LogTo(Console.WriteLine).SetElasticsearchStartTimeout(60)).Ready())
                 settings = (Settings)elasticsearch.Settings;

@@ -128,7 +128,7 @@
         [Test]
         public void Has_specific_version()
         {
-            using (var elasticsearch = new Elasticsearch(i => i.SetPort(4444).EnableLogging()).ReadySync())
+            using (var elasticsearch = new Elasticsearch(i => i.SetPort(4444).EnableLogging().SetElasticsearchStartTimeout(60)).ReadySync())
             {
                 ////Arrange
                 var client = new ElasticClient(new ConnectionSettings(elasticsearch.Url));
@@ -148,7 +148,7 @@
             const string relativeSource = "TestFiles/testfile.txt";
             var sourceFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
             var sourcePath = Path.Combine(sourceFolder, relativeSource);
-            using (var elasticsearch = await new Elasticsearch(c => c.SetPort(4444).EnableLogging().AddFile(relativeDestination, sourcePath)).Ready())
+            using (var elasticsearch = await new Elasticsearch(c => c.SetPort(4444).EnableLogging().AddFile(relativeDestination, sourcePath).SetElasticsearchStartTimeout(60)).Ready())
             {
                 var settings = (Settings)elasticsearch.Settings;
                 var folder = settings.ElasticsearchConfigPath;


Using TException

Using TException

These code is meant to be rewritten

--- Core/System/Diagnostics/Contracts/Contract.net35.cs
+++ Core/System/Diagnostics/Contracts/Contract.net35.cs
@@ -165,6 +165,7 @@
         public static void EnsuresOnThrow<TException>(bool condition)
             where TException : Exception
         {
+            GC.KeepAlive(typeof(TException));
             GC.KeepAlive(condition);
             AssertMustUseRewriter(ContractFailureKind.PostconditionOnException, "EnsuresOnThrow");
         }
@@ -185,6 +186,7 @@
         public static void EnsuresOnThrow<TException>(bool condition, string userMessage)
             where TException : Exception
         {
+            GC.KeepAlive(typeof(TException));
             GC.KeepAlive(condition);
             GC.KeepAlive(userMessage);
             AssertMustUseRewriter(ContractFailureKind.PostconditionOnException, "EnsuresOnThrow");
@@ -429,6 +431,7 @@
         public static void Requires<TException>(bool condition)
             where TException : Exception
         {
+            GC.KeepAlive(typeof(TException));
             GC.KeepAlive(condition);
             AssertMustUseRewriter(ContractFailureKind.Precondition, "Requires<TException>");
         }
@@ -448,6 +451,7 @@
         public static void Requires<TException>(bool condition, string userMessage)
             where TException : Exception
         {
+            GC.KeepAlive(typeof(TException));
             GC.KeepAlive(condition);
             GC.KeepAlive(userMessage);
             AssertMustUseRewriter(ContractFailureKind.Precondition, "Requires<TException>");


Fixed datetime format to one that elastic search automatically picks up

--- source/LogFlow/Builtins/Outputs/ElasticSearchOutput.cs
+++ source/LogFlow/Builtins/Outputs/ElasticSearchOutput.cs
@@ -109,7 +109,7 @@
 				throw new ArgumentNullException(ElasticSearchFields.Timestamp);
 			}

-			var timestampIsoString = result.EventTimeStamp.Value.ToString("o", CultureInfo.InvariantCulture);
+			var timestampIsoString = result.EventTimeStamp.Value.ToString(@"yyyy-MM-ddTHH\:mm\:ss.fff", CultureInfo.InvariantCulture);
 			if(result.Json[ElasticSearchFields.Timestamp] == null)
 			{
 				result.Json.Add(ElasticSearchFields.Timestamp, new JValue(timestampIsoString));


add test to reproduce metadata caching issues

--- src/Simple.OData.Client.UnitTests/Core/MetadataCacheTests.cs
+++ src/Simple.OData.Client.UnitTests/Core/MetadataCacheTests.cs
@@ -40,5 +40,23 @@
             Assert.False(wasCached);
             Assert.Null(cached);
         }
+
+        [Fact]
+        public async Task MetadataIsCached()
+        {
+            var baseUri = new Uri("http://services.odata.org/V3/OData/OData.svc/");
+            var settings = new ODataClientSettings{ BaseUri = baseUri};
+            var client = new ODataClient(settings);
+
+            await client.GetMetadataAsync();
+            MetadataCache.GetOrAdd(baseUri.ToString(), x => throw new Exception("metadata was not cached"));
+
+            settings.BeforeRequest = x => throw new Exception("metadata cache was not used");
+            await client.GetMetadataAsync();
+
+            settings = new ODataClientSettings{BaseUri = baseUri, BeforeRequest = x=>throw new Exception("not reusing settings with defeat metadata cache")};
+            client = new ODataClient(settings);
+            await client.GetMetadataAsync();
+        }
     }
 }


MeidoBot: Shuffle some code around

MeidoBot: Shuffle some code around

--- MeidoBot/Dispatch/Dispatcher.cs
+++ MeidoBot/Dispatch/Dispatcher.cs
@@ -84,21 +84,8 @@
             }
         }

+
         // --- Dispatching the correct things in the correct way ---
-
-        // • Unique queue: queue per trigger/handler
-        //   [one-to-one]
-
-        // • Shared queue: queue per plugin
-        //   [many-to-one]
-
-        // • Threadpool: Reentrant chaos
-        //   [many-to-many]
-
-        // • Standard/Default: single shared queue for all
-        //   [many-to-one]
-
-        // Only the last 3 are implemented for now.

         void DoTrigger(IrcMsg msg)
         {
@@ -136,6 +123,58 @@
         }

+        // --- Dispatch threading and queue logic ---
+
+        // • Unique queue: queue per trigger/handler
+        //    [one-to-one]
+        // • Shared queue: queue per plugin
+        //    [many-to-one]
+        // • Threadpool: Reentrant chaos
+        //    [many-to-many]
+        // • Standard/Default: single shared queue for all
+        //    [many-to-one]
+        // Only the last 3 are implemented for now.
+
+        // Process triggers and IRC event handlers declared by the plugin.
+        public void ProcessPluginDeclares(MeidoPlugin plugin)
+        {
+            // Shared queue for all triggers or IRC even handlers declared by the plugin,
+            // that is if they have opted for ThreadingModel.Queue.
+            Queue<Action> queue = null;
+
+            foreach (var tr in plugin.Triggers)
+            {
+                if (triggers.AddTrigger(tr, plugin))
+                    RegisterThreading(tr.Threading, tr, triggerQueues, ref queue);
+            }
+            foreach (var handler in plugin.Handlers)
+            {
+                if (ircEvents.AddHandler(handler))
+                    RegisterThreading(handler.Threading, handler, eventQueues, ref queue);
+            }
+
+            if (queue != null)
+                StartConsumeThread(queue);
+        }
+
+        // Map `id` to `queue` via a Dictionary in a way determined by ThreadingModel.
+        static void RegisterThreading<T>(
+            TriggerThreading threading,
+            T id,
+            Dictionary<T, Queue<Action>> map,
+            ref Queue<Action> queue)
+        {
+            if (threading == TriggerThreading.Queue)
+            {
+                if (queue == null)
+                    queue = new Queue<Action>();
+
+                map[id] = queue;
+            }
+            // We don't need to do anything for other types of threading.
+        }
+
+        // Dispatch the correct delegate to the correct queue (or Threadpool) according to `threading`.
         void ThreadingDispatch<T>(
             TriggerThreading threading,
             Action queueDelegate,
@@ -165,7 +204,7 @@
         }

-        // --- Enqueing, consuming and threading ---
+        // --- Enqueing, consuming and threading boilerplate ---

         static void Push(Action action, Queue<Action> q)
         {
@@ -175,46 +214,6 @@
                 Monitor.Pulse(q);
             }
         }
-
-
-        public void ProcessPluginDeclares(MeidoPlugin plugin)
-        {
-            // Shared queue for all triggers or IRC even handlers declared by the plugin,
-            // that is if they have opted for ThreadingModel.Queue.
-            Queue<Action> queue = null;
-
-            foreach (var tr in plugin.Triggers)
-            {
-                if (triggers.AddTrigger(tr, plugin))
-                    RegisterThreading(tr.Threading, tr, triggerQueues, ref queue);
-            }
-            foreach (var handler in plugin.Handlers)
-            {
-                if (ircEvents.AddHandler(handler))
-                    RegisterThreading(handler.Threading, handler, eventQueues, ref queue);
-            }
-
-            if (queue != null)
-                StartConsumeThread(queue);
-        }
-
-        // Map `id` to `queue` via a Dictionary in a way determined by ThreadingModel.
-        static void RegisterThreading<T>(
-            TriggerThreading threading,
-            T id,
-            Dictionary<T, Queue<Action>> map,
-            ref Queue<Action> queue)
-        {
-            if (threading == TriggerThreading.Queue)
-            {
-                if (queue == null)
-                    queue = new Queue<Action>();
-
-                map[id] = queue;
-            }
-            // We don't need to do anything for other types of threading.
-        }
-

         static void StartConsumeThread(Queue<Action> queue)
         {


Thing breaking CC.

Thing breaking CC.

--- Cogito.ServiceFabric.Activities.Test.TestActor/Test.cs
+++ Cogito.ServiceFabric.Activities.Test.TestActor/Test.cs
@@ -29,13 +29,7 @@
         protected override Activity CreateActivity()
         {
             return Sequence(
-                Wait("Start"),
-                ForEach(async () => Enumerable.Range(0, 5).Select(i => ActorProxy.Create<ITest2>(ActorId.CreateRandom())).ToArray(),
-                   arg => Sequence(
-                       Invoke(async () => await DoThing1()),
-                       Delay(TimeSpan.FromSeconds(10)),
-                       new Persist()
-                       )));
+                Wait("Start"));
         }

         async Task DoThing1()


Make sure to save/restore the canvas matrix

--- source/SkiaSharp.Views/SkiaSharp.Views.Gtk/SKWidget.cs
+++ source/SkiaSharp.Views/SkiaSharp.Views.Gtk/SKWidget.cs
@@ -28,8 +28,11 @@
 			// get the pixbuf
 			CreateDrawingObjects();

-				// start drawing
-			OnPaintSurface(new SKPaintSurfaceEventArgs(surface, imgInfo));
+			// start drawing
+			using (new SKAutoCanvasRestore(surface.Canvas, true))
+			{
+				OnPaintSurface(new SKPaintSurfaceEventArgs(surface, imgInfo));
+			}

 			surface.Canvas.Flush();


Formatting fixes for unpacked .savs

Formatting fixes for unpacked .savs

--- PawnManager/src/SavTab.cs
+++ PawnManager/src/SavTab.cs
@@ -106,14 +106,15 @@

             PawnIO.SavePawnSav(exportPawn, SavSourcePawn, savRoot);

+            string encoded = EncodeXml(savRoot);
+
             if (isPacked == true)
             {
-                string encoded = EncodeXml(savRoot);
                 SavTool.RepackSav(SavPath, encoded);
             }
             else if (isPacked == false)
             {
-                savRoot.Save(SavPath, SaveOptions.DisableFormatting);
+                File.WriteAllText(SavPath, encoded, new UTF8Encoding(false));
             }
         }


David/Stephen - removed debugging info

David/Stephen - removed debugging info

--- src/StockportWebapp/Views/stockportgov/Shared/_Layout.cshtml
+++ src/StockportWebapp/Views/stockportgov/Shared/_Layout.cshtml
@@ -45,8 +45,6 @@
     @RenderSection("Breadcrumbs", false)

         @RenderBody()
-
-
@CurrentEnvironment.Name

     <distributed-cache name="footer" expires-after="@TimeSpan.FromMinutes(ApplicationConfiguration.GetFooterCache(BusinessId.ToString()))" enabled="true">
         @await Component.InvokeAsync("Footer")


Mark BrokerageModelSecurityInitializer.Initialize as virtual

--- Common/Securities/BrokerageModelSecurityInitializer.cs
+++ Common/Securities/BrokerageModelSecurityInitializer.cs
@@ -41,7 +41,7 @@
         /// Initializes the specified security by setting up the models
         /// </summary>
         /// <param name="security">The security to be initialized</param>
-        public void Initialize(Security security)
+        public virtual void Initialize(Security security)
         {
             // set leverage and models
             security.SetLeverage(_brokerageModel.GetLeverage(security));


CHT test: Chain tip advancement and keeping correct block data - issue 37 and 38 (#1592)

* Added test for 37

* Added test for 38

* Updated as per feedback

* Moved ConsensusTipChanged out of the loop

* Fixed merge conflicts

--- src/Stratis.Bitcoin.Tests/Consensus/ChainedHeaderTreeTest.cs
+++ src/Stratis.Bitcoin.Tests/Consensus/ChainedHeaderTreeTest.cs
@@ -12,6 +12,7 @@
 using Stratis.Bitcoin.Configuration.Settings;
 using Stratis.Bitcoin.Consensus;
 using Stratis.Bitcoin.Consensus.Validators;
+using Stratis.Bitcoin.Primitives;
 using Stratis.Bitcoin.Utilities;
 using Xunit;

@@ -1377,7 +1378,7 @@
             cht.PeerDisconnected(peer1Id);

             // Attempt to call PartialValidationSucceeded on a saved bock.
-            List<ChainedHeader> headersToValidate = cht.PartialValidationSucceeded(firstPresentedHeader, out bool fullValidationRequired);
+            List<ChainedHeaderBlock> headersToValidate = cht.PartialValidationSucceeded(firstPresentedHeader, out bool fullValidationRequired);
             headersToValidate.Should().BeNull();
             fullValidationRequired.Should().BeFalse();
         }
@@ -1422,5 +1423,134 @@
             currentHeaders.Should().ContainKey(allHeaders[2].HashBlock);
             currentHeaders[allHeaders[2].HashBlock].Next.Should().BeEmpty();
         }
+
+        /// <summary>
+        /// Issue 37 @ CT advances at 1000 blocks. Make sure that block data for headers 1-900 are removed.
+        /// </summary>
+        [Fact]
+        public void ChainTipAdvancesAt1000Blocks_DataForHeadersForFirst900HeadersAreRemoved()
+        {
+            // Chain header tree setup. Initial chain has 1 header.
+            // Example: h1.
+            const int initialChainSize = 1;
+            TestContext ctx = new TestContextBuilder().WithInitialChain(initialChainSize).Build();
+            ChainedHeaderTree cht = ctx.ChainedHeaderTree;
+            ChainedHeader chainTip = ctx.InitialChainTip;
+
+            // Extend a chain by 1000 headers.
+            // Example: h1=h2=...=h1001.
+            const int extensionSize = 1000;
+            chainTip = ctx.ExtendAChain(extensionSize, chainTip);
+            List<BlockHeader> listOfCurrentChainHeaders = ctx.ChainedHeaderToList(chainTip, extensionSize);
+
+            // Peer 1 presents a chain.
+            const int peerId = 1;
+            ConnectNewHeadersResult connectionResult = cht.ConnectNewHeaders(peerId, listOfCurrentChainHeaders);
+            ChainedHeader[] consumedHeaders = connectionResult.Consumed.ToArray(extensionSize);
+            ChainedHeader[] originalHeaders = chainTip.ToArray(extensionSize);
+
+            // Sync all blocks.
+            for (int i = 0; i < extensionSize; i++)
+            {
+                ChainedHeader currentChainTip = consumedHeaders[i];
+
+                cht.BlockDataDownloaded(currentChainTip, originalHeaders[i].Block);
+                cht.PartialValidationSucceeded(currentChainTip, out bool fullValidationRequired);
+                cht.ConsensusTipChanged(currentChainTip);
+            }
+
+            // Headers 2-901 should have block data null.
+            // Headers 901 - 1001 should have block data.
+            Dictionary<uint256, ChainedHeader> connectedHeaders = cht.GetChainedHeadersByHash();
+            foreach (ChainedHeader consumedHeader in consumedHeaders)
+            {
+                if (consumedHeader.Height <= (extensionSize - ChainedHeaderTree.KeepBlockDataForLastBlocks))
+                {
+                    connectedHeaders[consumedHeader.HashBlock].Block.Should().BeNull();
+                }
+                else
+                {
+                    connectedHeaders[consumedHeader.HashBlock].Block.Should().NotBeNull();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Issue 38 @ CT advances at 150. Alternative chain with fork at 120 and total length 160 is presented.
+        /// CT switches to 160. Make sure block data for 0-60 is removed.
+        /// </summary>
+        [Fact]
+        public void ChainTipAdvancesAt150Blocks_AlternativeChainPresented_RelevantBlockDataIsRemoved()
+        {
+            // Chain header tree setup. Initial chain has 1 header.
+            // Example: h1.
+            const int initialChainSize = 1;
+            TestContext ctx = new TestContextBuilder().WithInitialChain(initialChainSize).Build();
+            ChainedHeaderTree cht = ctx.ChainedHeaderTree;
+            ChainedHeader chainTip = ctx.InitialChainTip;
+
+            // Create a chain A with 150 headers.
+            // Example: h1=h2=...h120=h121=a122=a123=a124=...=a151.
+            const int extensionBeforeFork = 120;
+            const int chainAExtensionSize = 150;
+            chainTip = ctx.ExtendAChain(extensionBeforeFork, chainTip);
+            ChainedHeader chainATip = ctx.ExtendAChain(chainAExtensionSize - extensionBeforeFork, chainTip);
+            List<BlockHeader> listOfCurrentChainAHeaders = ctx.ChainedHeaderToList(chainATip, chainAExtensionSize);
+
+            // Peer 1 presents a chain A.
+            const int peer1Id = 1;
+            ConnectNewHeadersResult connectionResult = cht.ConnectNewHeaders(peer1Id, listOfCurrentChainAHeaders);
+            ChainedHeader[] consumedChainAHeaders = connectionResult.Consumed.ToArray(chainAExtensionSize);
+            ChainedHeader[] originalChainAHeaders = chainATip.ToArray(chainAExtensionSize);
+
+            // Sync all blocks for chain A.
+            for (int i = 0; i < chainAExtensionSize; i++)
+            {
+                ChainedHeader currentChainTip = consumedChainAHeaders[i];
+
+                cht.BlockDataDownloaded(currentChainTip, originalChainAHeaders[i].Block);
+                cht.PartialValidationSucceeded(currentChainTip, out bool fullValidationRequired);
+                cht.ConsensusTipChanged(currentChainTip);
+            }
+
+            // Create a chain B with 160 headers and a fork at 121.
+            // Example: h1=h2=...h120=h121=b122=b123=b124=...=b161.
+            const int chainBExtensionSize = 160;
+            ChainedHeader chainBTip = ctx.ExtendAChain(chainBExtensionSize - extensionBeforeFork, chainTip);
+            List<BlockHeader> listOfCurrentChainBHeaders = ctx.ChainedHeaderToList(chainBTip, chainBExtensionSize - extensionBeforeFork);
+
+            // Peer 2 presents a chain B.
+            const int peer2Id = 2;
+            connectionResult = cht.ConnectNewHeaders(peer2Id, listOfCurrentChainBHeaders);
+            ChainedHeader[] consumedChainBHeaders = connectionResult.Consumed.ToArray(chainBExtensionSize - extensionBeforeFork);
+            ChainedHeader[] originalChainBHeaders = chainBTip.ToArray(chainBExtensionSize - extensionBeforeFork);
+
+            // Sync all new blocks for chain B.
+            for (int i = 0; i < chainBExtensionSize - extensionBeforeFork; i++)
+            {
+                ChainedHeader currentChainTip = consumedChainBHeaders[i];
+
+                cht.BlockDataDownloaded(currentChainTip, originalChainBHeaders[i].Block);
+                cht.PartialValidationSucceeded(currentChainTip, out bool fullValidationRequired);
+            }
+
+            cht.ConsensusTipChanged(connectionResult.Consumed);
+
+            // Headers 2-60 should have block data null.
+            // Headers 61 - 161 should have block data.
+            Dictionary<uint256, ChainedHeader> connectedHeaders = cht.GetChainedHeadersByHash();
+            ChainedHeader[] allChainBHeaders = connectionResult.Consumed.ToArray(chainBExtensionSize);
+            foreach (ChainedHeader consumedHeader in allChainBHeaders)
+            {
+                if (consumedHeader.Height <= (chainBExtensionSize - ChainedHeaderTree.KeepBlockDataForLastBlocks))
+                {
+                    connectedHeaders[consumedHeader.HashBlock].Block.Should().BeNull();
+                }
+                else
+                {
+                    connectedHeaders[consumedHeader.HashBlock].Block.Should().NotBeNull();
+                }
+            }
+        }
     }
 }


Cleanup WebUtility tests

Cleanup WebUtility tests

- Use xunit InlineData

--- src/System.Runtime.Extensions/tests/System/Net/WebUtility.cs
+++ src/System.Runtime.Extensions/tests/System/Net/WebUtility.cs
@@ -2,165 +2,130 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.

+using System.Collections.Generic;
+
 using Xunit;
-
+
 namespace System.Net.Tests
 {
     public class WebUtilityTests
     {
-        [Fact]
-        public static void HtmlDecodeWithoutTextWriter()
+        public static IEnumerable<object[]> HtmlDecode_TestData()
         {
-            string input = "Hello! '"<&>\u2665♥\u00E7çç";
-            string expected = "Hello! '\"<&>\u2665\u2665\u00E7\u00E7\u00E7";
+            yield return new object[] { "Hello! '"<&>\u2665♥\u00E7çç", "Hello! '\"<&>\u2665\u2665\u00E7\u00E7\u00E7" };
+            yield return new object[] { "Hello, world! \"<>\u2665\u00E7", "Hello, world! \"<>\u2665\u00E7" }; // No special chars
+            yield return new object[] { null, null };

-            string returned = WebUtility.HtmlDecode(input);
-
-            Assert.Equal(expected, returned);
+            yield return new object[] { "𣎴", char.ConvertFromUtf32(144308) };
         }

-        [Fact]
-        public static void HtmlDecodeWithoutTextWriterReturnsNullIfInputIsNull()
+        [Theory, MemberData("HtmlDecode_TestData")]
+        public static void HtmlDecode(string value, string expected)
         {
-            string returned = WebUtility.HtmlDecode(null);
-            Assert.Null(returned);
+            Assert.Equal(expected, WebUtility.HtmlDecode(value));
         }

-        [Fact]
-        public static void HtmlDecodeNoTextWriterOriginalStringNoSpecialCharacters()
-        {
-            string input = "Hello, world! \"<>\u2665\u00E7";
-
-            string returned = WebUtility.HtmlDecode(input);
-
-            Assert.Equal(input, returned);
-        }
-
-        [Fact]
-        public static void HtmlEncodeSingleQuote()
+        public static IEnumerable<object[]> HtmlEncode_TestData()
         {
             // Single quotes need to be encoded as ' rather than ' since ' is valid both for
             // HTML and XHTML, but ' is valid only for XHTML.
             // For more info: http://fishbowl.pastiche.org/2003/07/01/the_curse_of_apos/
+            yield return new object[] { "'", "'" };
+            yield return new object[] { "Hello! '\"<&>\u2665\u00E7 World", "Hello! '"<&>\u2665ç World" };
+            yield return new object[] { null, null };
+            yield return new object[] { "Hello, world!", "Hello, world!" }; // No special chars

-            string input = "'";
-            string expected = "'";
-
-            string returned = WebUtility.HtmlEncode(input);
-
-            Assert.Equal(expected, returned);
+            yield return new object[] { char.ConvertFromUtf32(144308), "𣎴" }; // Default strict settings
         }

-        [Fact]
-        public static void HtmlEncodeWithoutTextWriter()
+        [Theory, MemberData("HtmlEncode_TestData")]
+        public static void HtmlEncode(string value, string expected)
         {
-            string input = "Hello! '\"<&>\u2665\u00E7 World";
-            string expected = "Hello! '"<&>\u2665ç World";
-
-            string returned = WebUtility.HtmlEncode(input);
-
-            Assert.Equal(expected, returned);
+            Assert.Equal(expected, WebUtility.HtmlEncode(value));
         }

-        [Fact]
-        public static void HtmlEncodeWithoutTextWriterReturnsNullIfInputIsNull()
+        public static IEnumerable<object[]> UrlDecode_TestData()
         {
-            string returned = WebUtility.HtmlEncode((string)null);
-
-            Assert.Null(returned);
+            // Recent change brings function inline with RFC 3986 to return hex-encoded chars in uppercase
+            yield return new object[] { "%2F%5C%22%09Hello!+%E2%99%A5%3F%2F%5C%22%09World!+%E2%99%A5%3F%E2%99%A5", "/\\\"\tHello! \u2665?/\\\"\tWorld! \u2665?\u2665" };
+            yield return new object[] { "Hello, world", "Hello, world" }; // No special chars
+            yield return new object[] { null, null };
         }

-        [Fact]
-        public static void HtmlEncodeNoTextWriterOriginalStringNoSpecialCharacters()
+        [Theory, MemberData("UrlDecode_TestData")]
+        public static void UrlDecode(string encodedValue, string expected)
         {
-            string input = "Hello, world!";
-
-            string returned = WebUtility.HtmlEncode(input);
-
-            Assert.Equal(input, returned);
+            Assert.Equal(expected, WebUtility.UrlDecode(encodedValue));
         }

-        [Fact]
-        public static void UrlDecodeFromStringNoEncodingReturnsNullIfInputIsNull()
+        public static IEnumerable<object[]> UrlEncode_TestData()
         {
-            string returned = WebUtility.UrlDecode((string)null);
-
-            Assert.Null(returned);
+            // Recent change brings function inline with RFC 3986 to return hex-encoded chars in uppercase
+            yield return new object[] { "/\\\"\tHello! \u2665?/\\\"\tWorld! \u2665?\u2665", "%2F%5C%22%09Hello!+%E2%99%A5%3F%2F%5C%22%09World!+%E2%99%A5%3F%E2%99%A5" };
+            yield return new object[] { "'", "%27" };
+            yield return new object[] { null, null };
         }

-        [Fact]
-        public static void UrlEncodeFromStringNoEncoding()
+        [Theory, MemberData("UrlEncode_TestData")]
+        public static void UrlEncode(string value, string expected)
         {
-            // Recent change brings function inline with RFC 3986 to return hex-encoded chars in uppercase
-            string input = "/\\\"\tHello! \u2665?/\\\"\tWorld! \u2665?\u2665";
-            string expected = "%2F%5C%22%09Hello!+%E2%99%A5%3F%2F%5C%22%09World!+%E2%99%A5%3F%E2%99%A5";
-
-            string returned = WebUtility.UrlEncode(input);
-
-            Assert.Equal(expected, returned);
-        }
-
-        [Fact]
-        public static void UrlEncodeFromStringNoEncodingReturnsNullIfInputIsNull()
-        {
-            string returned = WebUtility.UrlEncode((string)null);
-            Assert.Null(returned);
-        }
-
-        [Fact]
-        public static void UrlEncodeToBytes_ArgumentValidation()
-        {
-            Assert.Null(WebUtility.UrlEncodeToBytes(null, 0, 0));
-            Assert.Throws<ArgumentNullException>("bytes", () => WebUtility.UrlEncodeToBytes(null, 0, 1));
-            Assert.Throws<ArgumentOutOfRangeException>("offset", () => WebUtility.UrlEncodeToBytes(new byte[1], -1, 1));
-            Assert.Throws<ArgumentOutOfRangeException>("offset", () => WebUtility.UrlEncodeToBytes(new byte[1], 2, 1));
-            Assert.Throws<ArgumentOutOfRangeException>("count", () => WebUtility.UrlEncodeToBytes(new byte[1], 0, -1));
-            Assert.Throws<ArgumentOutOfRangeException>("count", () => WebUtility.UrlEncodeToBytes(new byte[1], 0, 3));
-        }
-
-        [Fact]
-        public static void UrlDecodeToBytes_ArgumentValidation()
-        {
-            Assert.Null(WebUtility.UrlDecodeToBytes(null, 0, 0));
-            Assert.Throws<ArgumentNullException>("bytes", () => WebUtility.UrlDecodeToBytes(null, 0, 1));
-            Assert.Throws<ArgumentOutOfRangeException>("offset", () => WebUtility.UrlDecodeToBytes(new byte[1], -1, 1));
-            Assert.Throws<ArgumentOutOfRangeException>("offset", () => WebUtility.UrlDecodeToBytes(new byte[1], 2, 1));
-            Assert.Throws<ArgumentOutOfRangeException>("count", () => WebUtility.UrlDecodeToBytes(new byte[1], 0, -1));
-            Assert.Throws<ArgumentOutOfRangeException>("count", () => WebUtility.UrlDecodeToBytes(new byte[1], 0, 3));
-        }
-
-        [Fact]
-        public static void UrlDecodeToBytesNullIfInputIsNull()
-        {
-            Assert.Null(WebUtility.UrlDecodeToBytes(null, 0, 0));
-        }
-
-        [Fact]
-        public static void UrlEncodeSingleQuote()
-        {
-            Assert.Equal("%27", WebUtility.UrlEncode("'"));
-        }
-
-        [Fact]
-        public static void HtmlDefaultStrictSettingEncode()
-        {
-            Assert.Equal(WebUtility.HtmlEncode(Char.ConvertFromUtf32(144308)), "𣎴");
-        }
-
-        [Fact]
-        public static void HtmlDefaultStrictSettingDecode()
-        {
-            Assert.Equal(Char.ConvertFromUtf32(144308), WebUtility.HtmlDecode("𣎴"));
+            Assert.Equal(expected, WebUtility.UrlEncode(value));
         }

         [Theory]
         [InlineData("'")]
         [InlineData("http://www.microsoft.com")]
         [InlineData("/\\\"\tHello! \u2665?/\\\"\tWorld! \u2665?\u2665")]
-        public static void UrlEncodeDecode_Roundtrip(string url)
+        public static void UrlEncodeDecode_Roundtrip(string value)
         {
-            string encoded = WebUtility.UrlEncode(url);
-            Assert.Equal(url, WebUtility.UrlDecode(encoded));
+            string encoded = WebUtility.UrlEncode(value);
+            Assert.Equal(value, WebUtility.UrlDecode(encoded));
+        }
+
+        public static IEnumerable<object[]> Url_DecodeToBytes_TestData()
+        {
+            yield return new object[] { null, 0, 0, null };
+        }
+
+        [Theory, MemberData("Url_DecodeToBytes_TestData")]
+        public static void UrlDecodeToBytes(byte[] encodedValue, int offset, int count, byte[] expected)
+        {
+            Assert.Equal(expected, WebUtility.UrlDecodeToBytes(encodedValue, offset, count));
+        }
+
+        [Fact]
+        public static void UrlDecodeToBytes_Invalid()
+        {
+            Assert.Throws<ArgumentNullException>("bytes", () => WebUtility.UrlDecodeToBytes(null, 0, 1)); // Bytes is null
+
+            Assert.Throws<ArgumentOutOfRangeException>("offset", () => WebUtility.UrlDecodeToBytes(new byte[1], -1, 1)); // Offset < 0
+            Assert.Throws<ArgumentOutOfRangeException>("offset", () => WebUtility.UrlDecodeToBytes(new byte[1], 2, 1)); // Offset > bytes.Length
+
+            Assert.Throws<ArgumentOutOfRangeException>("count", () => WebUtility.UrlDecodeToBytes(new byte[1], 0, -1)); // Count < 0
+            Assert.Throws<ArgumentOutOfRangeException>("count", () => WebUtility.UrlDecodeToBytes(new byte[1], 0, 3)); // Count > bytes.Length
+        }
+
+        public static IEnumerable<object[]> Url_EncodeToBytes_TestData()
+        {
+            yield return new object[] { null, 0, 0, null };
+        }
+
+        [Theory, MemberData("Url_EncodeToBytes_TestData")]
+        public static void UrlEncodeToBytes(byte[] value, int offset, int count, byte[] expected)
+        {
+            Assert.Equal(expected, WebUtility.UrlEncodeToBytes(value, offset, count));
+        }
+
+        [Fact]
+        public static void UrlEncodeToBytes_Invalid()
+        {
+            Assert.Throws<ArgumentNullException>("bytes", () => WebUtility.UrlEncodeToBytes(null, 0, 1)); // Bytes is null
+
+            Assert.Throws<ArgumentOutOfRangeException>("offset", () => WebUtility.UrlEncodeToBytes(new byte[1], -1, 1)); // Offset < 0
+            Assert.Throws<ArgumentOutOfRangeException>("offset", () => WebUtility.UrlEncodeToBytes(new byte[1], 2, 1)); // Offset > bytes.Length
+
+            Assert.Throws<ArgumentOutOfRangeException>("count", () => WebUtility.UrlEncodeToBytes(new byte[1], 0, -1)); // Count < 0
+            Assert.Throws<ArgumentOutOfRangeException>("count", () => WebUtility.UrlEncodeToBytes(new byte[1], 0, 3)); // Count > bytes.Length
         }

         [Theory]


- Quality improvements to WebSocketBase Receive() method

--- Mixer.Base/Web/WebSocketBase.cs
+++ Mixer.Base/Web/WebSocketBase.cs
@@ -100,6 +100,7 @@
         {
             string jsonBuffer = string.Empty;
             byte[] buffer = new byte[WebSocketBase.bufferSize];
+            ArraySegment<byte> arrayBuffer = new ArraySegment<byte>(buffer);

             WebSocketCloseStatus closeStatus = WebSocketCloseStatus.NormalClosure;

@@ -110,13 +111,17 @@
                     try
                     {
                         Array.Clear(buffer, 0, buffer.Length);
-                        WebSocketReceiveResult result = await this.webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
+                        WebSocketReceiveResult result = await this.webSocket.ReceiveAsync(arrayBuffer, CancellationToken.None);

                         if (result != null)
                         {
-                            if (result.CloseStatus == null || result.CloseStatus == WebSocketCloseStatus.Empty)
+                            if (result.MessageType == WebSocketMessageType.Close || (result.CloseStatus != null && result.CloseStatus.GetValueOrDefault() != WebSocketCloseStatus.Empty))
                             {
-                                jsonBuffer += this.encoder.GetString(buffer);
+                                closeStatus = result.CloseStatus.GetValueOrDefault();
+                            }
+                            else if (result.MessageType == WebSocketMessageType.Text)
+                            {
+                                jsonBuffer += this.encoder.GetString(buffer, 0, result.Count);
                                 if (result.EndOfMessage)
                                 {
                                     if (this.OnReceivedOccurred != null)
@@ -125,13 +130,12 @@
                                     }

                                     await this.ProcessReceivedPacket(jsonBuffer);
-
                                     jsonBuffer = string.Empty;
                                 }
                             }
                             else
                             {
-                                closeStatus = result.CloseStatus.GetValueOrDefault();
+                                Logger.Log("Unsupported packet received");
                             }
                         }
                     }
@@ -139,6 +143,7 @@
                     {
                         Logger.Log(ex);
                         closeStatus = WebSocketCloseStatus.InternalServerError;
+                        jsonBuffer = string.Empty;
                     }
                 }
             }


Changed BoboBrowser.GetFacetHandler(string) to an override.

--- src/BoboBrowse.Net/BoboBrowse.Net/BoboBrowser.cs
+++ src/BoboBrowse.Net/BoboBrowse.Net/BoboBrowser.cs
@@ -105,7 +105,7 @@
             get { return _subBrowsers[0].FacetNames; }
         }

-        public virtual IFacetHandler GetFacetHandler(string name)
+        public override IFacetHandler GetFacetHandler(string name)
         {
             return _subBrowsers[0].GetFacetHandler(name);
         }


v2.0 Trunk: Improved a few xml code docs.

--- src/Caliburn.PresentationFramework/Views/View.cs
+++ src/Caliburn.PresentationFramework/Views/View.cs
@@ -39,8 +39,8 @@
         /// <summary>
         /// Gets the context.
         /// </summary>
-        /// <param name="d">The d.</param>
-        /// <returns></returns>
+        /// <param name="d">The element the context is attached to.</param>
+        /// <returns>The context.</returns>
         public static object GetContext(DependencyObject d)
         {
             return d.GetValue(ContextProperty);
@@ -49,8 +49,8 @@
         /// <summary>
         /// Sets the context.
         /// </summary>
-        /// <param name="d">The d.</param>
-        /// <param name="value">The value.</param>
+        /// <param name="d">The element to attach the context to.</param>
+        /// <param name="value">The context.</param>
         public static void SetContext(DependencyObject d, object value)
         {
             d.SetValue(ContextProperty, value);
@@ -70,8 +70,8 @@
         /// <summary>
         /// Gets the model.
         /// </summary>
-        /// <param name="d">The d.</param>
-        /// <returns></returns>
+        /// <param name="d">The element the model is attached to.</param>
+        /// <returns>The model.</returns>
         public static object GetModel(DependencyObject d)
         {
             return d.GetValue(ModelProperty);
@@ -80,8 +80,8 @@
         /// <summary>
         /// Sets the model.
         /// </summary>
-        /// <param name="d">The d.</param>
-        /// <param name="value">The value.</param>
+        /// <param name="d">The element to attach the model to.</param>
+        /// <param name="value">The model.</param>
         public static void SetModel(DependencyObject d, object value)
         {
             d.SetValue(ModelProperty, value);
@@ -102,7 +102,7 @@
         /// <summary>
         /// Gets the <see cref="IViewLocator"/>.
         /// </summary>
-        /// <param name="d">The d.</param>
+        /// <param name="d">The element the strategy is attached to.</param>
         /// <returns>The strategy.</returns>
         public static IViewLocator GetStrategy(DependencyObject d)
         {
@@ -112,8 +112,8 @@
         /// <summary>
         /// Sets the <see cref="IViewLocator"/>.
         /// </summary>
-        /// <param name="d">The d.</param>
-        /// <param name="value">The value.</param>
+        /// <param name="d">The element to attach the strategy to.</param>
+        /// <param name="value">The strategy.</param>
         public static void SetStrategy(DependencyObject d, IViewLocator value)
         {
             d.SetValue(StrategyProperty, value);
@@ -133,8 +133,8 @@
         /// <summary>
         /// Gets the convention application behavior.
         /// </summary>
-        /// <param name="d">The d.</param>
-        /// <returns>The strategy.</returns>
+        /// <param name="d">The element the property is attached to.</param>
+        /// <returns>Whether or not to apply conventions.</returns>
         public static bool? GetApplyConventions(DependencyObject d)
         {
             return (bool?)d.GetValue(ApplyConventionsProperty);
@@ -143,8 +143,8 @@
         /// <summary>
         /// Sets the convention application behavior.
         /// </summary>
-        /// <param name="d">The d.</param>
-        /// <param name="value">The value.</param>
+        /// <param name="d">The element to attach the property to.</param>
+        /// <param name="value">Whether or not to apply conventions.</param>
         public static void SetApplyConventions(DependencyObject d, bool? value)
         {
             d.SetValue(ApplyConventionsProperty, value);


DIctionary

DIctionary

--- src/Map/TileMap.cs
+++ src/Map/TileMap.cs
@@ -43,7 +43,7 @@
         //Dictionary containing all entities and their positions on the map
         Dictionary<Entity, Vector2> PlacedObjects = new Dictionary<Entity, Vector2>();

-        //DIctionary containing all entities and the team that they belong to
+        //Dictionary containing all entities and the team that they belong to
         Dictionary<Entity, Team> TeamDictionary = new Dictionary<Entity, Team>();

         public Texture2D HighlightTexture;


Adding a comment about support for ISymUnmanagedReader3...

--- src/Test/PdbUtilities/Shared/SymUnmanagedReaderExtensions.cs
+++ src/Test/PdbUtilities/Shared/SymUnmanagedReaderExtensions.cs
@@ -161,6 +161,11 @@
                 methodToken,
                 methodVersion,
                 (ISymUnmanagedReader pReader, int pMethodToken, int pMethodVersion, int pBufferLength, out int pCount, byte[] pCustomDebugInfo) =>
+                    // Note:  Here, we are assuming that the sym reader implementation we're using implements ISymUnmanagedReader3.  This is
+                    // necessary so that we get custom debug info for the correct method version in EnC scenarios.  However, some sym reader
+                    // implementations do not support this interface (for example, the mscordbi dynamic sym reader).  If we need to fall back
+                    // and call ISymUnmanagedReader.GetSymAttribute in those cases (assuming EnC is not supported), then we'll need to ensure
+                    // that incorrect or missing custom debug info will not cause problems for any callers of this method.
                     ((ISymUnmanagedReader3)pReader).GetSymAttributeByVersion(pMethodToken, pMethodVersion, CdiAttributeName, pBufferLength, out pCount, pCustomDebugInfo));
         }


窓関数にバートレット窓を追加

窓関数にバートレット窓を追加

--- src/Math/Window.cs
+++ src/Math/Window.cs
@@ -54,5 +54,16 @@
                     array[i] *= 0.54 - 0.46 * Math.Cos(factor * (i + 0.5));
         }

+        public static void Bartlett(double[] array)
+        {
+            int length = array.Length;
+
+            if (length % 2 == 0)
+                for (int i = 0; i < length; i++)
+                    array[i] *= 1.0 - 2.0 * Math.Abs(i / (double)length - 0.5);
+            else
+                for (int i = 0; i < length; i++)
+                    array[i] *= 1.0 - 2.0 * Math.Abs((i + 0.5) / (double)length - 0.5);
+        }
     }
 }


Fixed TestElementBase to calculate better state.

--- src/TestFx.ReSharper/UnitTesting/Elements/TestElementBase.cs
+++ src/TestFx.ReSharper/UnitTesting/Elements/TestElementBase.cs
@@ -122,11 +122,25 @@
       get { return _state; }
       set
       {
-        _state = value;
+        _state = GetState(_state, value);

         if (value == UnitTestElementState.Invalid)
           _children.ForEach(x => x.State = UnitTestElementState.Invalid);
       }
+    }
+
+    private UnitTestElementState GetState (UnitTestElementState currentState, UnitTestElementState newState)
+    {
+      if (newState == UnitTestElementState.Valid && currentState == UnitTestElementState.PendingDynamic)
+        return UnitTestElementState.Dynamic;
+
+      if ((currentState == UnitTestElementState.Dynamic || currentState == UnitTestElementState.PendingDynamic) &&
+          (newState == UnitTestElementState.Valid || newState == UnitTestElementState.Pending))
+      {
+        throw new Exception(string.Format("Current state {0} unable to turn into {1}", currentState, newState));
+      }
+
+      return newState;
     }

     [CanBeNull]


Content: Implement IEquatable interface.

--- AIWolfLib/Content.cs
+++ AIWolfLib/Content.cs
@@ -23,7 +23,7 @@
     /// Content class.
     /// </summary>
 #endif
-    public class Content
+    public class Content : IEquatable<Content>
     {
 #if JHELP
         /// <summary>
@@ -293,6 +293,49 @@
             }
             return null;
         }
+
+#if JHELP
+        /// <summary>
+        /// 発話文字列が等しい場合trueを返す
+        /// </summary>
+        /// <param name="other">比較対象</param>
+        /// <returns>発話文字列が等しい場合true</returns>
+#else
+        /// <summary>
+        /// Returns true if text representation of this content equals that of other.
+        /// </summary>
+        /// <param name="other">Content to compare with this content.</param>
+        /// <returns>true if other equals this in text; otherwise, false.</returns>
+#endif
+        public bool Equals(Content other) => other == null ? false : this.Text == other.Text;
+
+#if JHELP
+        /// <summary>
+        /// 発話文字列が等しい場合trueを返す
+        /// </summary>
+        /// <param name="obj">比較対象</param>
+        /// <returns>発話文字列が等しい場合true</returns>
+#else
+        /// <summary>
+        /// Returns true if text representation of this content equals that of other.
+        /// </summary>
+        /// <param name="obj">Object to compare with this content.</param>
+        /// <returns>true if other equals this in text; otherwise, false.</returns>
+#endif
+        public override bool Equals(object obj) => obj == null || this.GetType() != obj.GetType() ? false : this.Equals((Content)obj);
+
+#if JHELP
+        /// <summary>
+        /// ハッシュ関数
+        /// </summary>
+        /// <returns>ハッシュ値</returns>
+#else
+        /// <summary>
+        /// Hash function.
+        /// </summary>
+        /// <returns>A hash code for the current object.</returns>
+#endif
+        public override int GetHashCode() => Text.GetHashCode();
     }

 #if JHELP


Add more constructors to MuffinClient

Add more constructors to MuffinClient

--- MuffinFramework/MuffinClient.cs
+++ MuffinFramework/MuffinClient.cs
@@ -1,5 +1,8 @@
 using System;
+using System.Collections.Generic;
 using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
 using System.Reflection;
 using MuffinFramework.Muffins;
 using MuffinFramework.Platforms;
@@ -22,6 +25,34 @@
             this.AggregateCatalog = new AggregateCatalog();
             this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetCallingAssembly()));

+            this.InitLoaders();
+        }
+
+        public MuffinClient(AggregateCatalog catalog)
+        {
+            this.AggregateCatalog = catalog;
+
+            this.InitLoaders();
+        }
+
+        public MuffinClient(ComposablePartCatalog catalog1, params ComposablePartCatalog[] catalogs)
+            : this(catalogs.Concat(new[] { catalog1 }))
+        {
+        }
+
+        public MuffinClient(IEnumerable<ComposablePartCatalog> catalogs)
+        {
+            this.AggregateCatalog = new AggregateCatalog();
+            foreach (var catalog in catalogs)
+            {
+                this.AggregateCatalog.Catalogs.Add(catalog);
+            }
+
+            this.InitLoaders();
+        }
+
+        private void InitLoaders()
+        {
             this.PlatformLoader = new PlatformLoader();
             this.ServiceLoader = new ServiceLoader();
             this.MuffinLoader = new MuffinLoader();


Update test for authenticated socks

Update test for authenticated socks

--- NBitcoin.Tests/ProtocolTests.cs
+++ NBitcoin.Tests/ProtocolTests.cs
@@ -18,6 +18,7 @@
 using NBitcoin.Tests.Helpers;
 using Xunit.Abstractions;
 using Xunit.Sdk;
+using NBitcoin.Protocol.Connectors;

 namespace NBitcoin.Tests
 {
@@ -816,6 +817,7 @@
 		// You need to run Tor Browser (the test use socks port 9150, not 9050)

 #pragma warning disable xUnit1013 // Public method should be marked as test
+		// [Fact]
 		public async Task TestDifferentConnectionMethods()
 #pragma warning restore xUnit1013 // Public method should be marked as test
 		{
@@ -839,7 +841,7 @@
 				// Should works for DNS names
 				"ec2-52-14-64-82.us-east-2.compute.amazonaws.com"
 				};
-			foreach (var onlyForOnionHosts in new[] { true, false })
+			foreach (var (onlyForOnionHosts, changeIpIdentities) in new[] { (true, true), (true, false), (false, true), (false, false) })
 			{
 				foreach (var endpoint in hosts.Select(h => Utils.ParseEndpoint(h, Network.Main.DefaultPort)))
 				{
@@ -849,6 +851,7 @@
 					{
 						var node = await Node.ConnectAsync(Network.Main, endpoint, new NodeConnectionParameters()
 						{
+							EndpointConnector = new DefaultEndpointConnector{ ChangeTorIdentities = changeIpIdentities },
 							TemplateBehaviors =
 							{
 								new SocksSettingsBehavior(Utils.ParseEndpoint("localhost", 9150), onlyForOnionHosts)


-3 ms

-3 ms

--- DereTore.Applications.ScoreEditor/PlayerSettings.cs
+++ DereTore.Applications.ScoreEditor/PlayerSettings.cs
@@ -26,7 +26,7 @@
         }

         // Compensates for ~3ms silence at the beginning of SFX files
-        public static TimeSpan SfxOffset { get; set; } = new TimeSpan(0, 0, 0, 0, 0);
+        public static TimeSpan SfxOffset { get; set; } = new TimeSpan(0, 0, 0, 0, -3);

         private static float _musicVolume = 0.7f;
         private static float _sfxVolume = 0.5f;


Fixed that passwords did not pass validation due to a type (Length instead of length)

--- Devshed.Web/Validation/PasswordStrengthValidator.cs
+++ Devshed.Web/Validation/PasswordStrengthValidator.cs
@@ -18,7 +18,7 @@
         DoesNotContainLetters: """ + Resources.Validation.DoesNotContainLetters + @""",
         DoesNotContainSpecialCharacter: """ + Resources.Validation.DoesNotContainSpecialCharacter + @"""
     },
-    CreatePassworScore: function (password, minLength)
+    CreatePasswordScore: function (password, minLength)
     {
 	    minLength = minLength || 8;
         var result = { score: 0, messages: [] };
@@ -34,12 +34,12 @@
             return result;
         }

-        if (password.Length >= minLength)
+        if (password.length >= minLength)
         {
             result.score++;
         }

-        if (password.Length >= minLength + 4)
+        if (password.length >= minLength + 4)
         {
             result.score++;
         }
@@ -101,17 +101,21 @@
             var script = @"
                 function " + functionName + @"(source, arguments)
                 {
-                    var result = BasicPasswordValidation.CreatePassworScore(arguments.Value);
+                    var result = BasicPasswordValidation.CreatePasswordScore(arguments.Value, " + MinimumLength + @");
                     arguments.IsValid = result.score >= " + (int)MinimumScore + @";

-                    var message = '';
-                    for(t = 0; t < result.messages.length; t++)
+                    if(result.messages.length > 0)
                     {
-                        message += ' - ' + result.messages[t] + '\n';
+                        var message = '';
+                        for(t = 0; t < result.messages.length; t++)
+                        {
+                            message += ' - ' + result.messages[t] + '\n';
+                        }
+
+                        alert(message);
                     }

                     console.log(result);
-                    alert(message);
                 }";

             this.ClientValidationFunction = functionName;


Fix so that SynchronisedAttribute works under VS2010

--- Dx.Runtime/Synchronisation/SynchronisedAttribute.cs
+++ Dx.Runtime/Synchronisation/SynchronisedAttribute.cs
@@ -6,8 +6,13 @@
     public class SynchronisedAttribute : Attribute
     {
         public Type StrategyType { get; set; }
-
-        public SynchronisedAttribute(Type strategyType = null)
+
+        public SynchronisedAttribute()
+        {
+            this.StrategyType = typeof(AssignmentStrategy);
+        }
+
+        public SynchronisedAttribute(Type strategyType)
         {
             if (strategyType == null)
                 strategyType = typeof(AssignmentStrategy);


debug logging

debug logging

--- EADatabaseTransformer/EADatabaseTransformerAddin.cs
+++ EADatabaseTransformer/EADatabaseTransformerAddin.cs
@@ -269,6 +269,9 @@

 		private void refreshCompare(bool refreshTransform)
 		{
+			//debug
+			Logger.log("start refreshCompare");
+			var timestamp = DateTime.Now;
 			//refresh transformation and load of new and original database
 			if (refreshTransform)
 			{
@@ -278,6 +281,9 @@
 			//compare again
 			_comparer.compare();
 			this.dbCompareControl.loadComparison(_comparer);
+			//debug
+			Logger.log("end refreshcompare. Total time taken : " + (DateTime.Now - timestamp).ToString() );
+
 		}


BigInteger parse fix

BigInteger parse fix

--- Framework.Core/System/Numerics/BigInteger.string.cs
+++ Framework.Core/System/Numerics/BigInteger.string.cs
@@ -340,7 +340,10 @@
                 if (allowLeadingSign)
                 {
                     number.Negative |= reader.Read(negativeSign);
-                    positive |= reader.Read(positiveSign);
+                    if (!number.Negative)
+                    {
+                        positive |= reader.Read(positiveSign);
+                    }
                 }
                 if (!number.Negative && allowParentheses && reader.Read('('))
                 {
@@ -437,8 +440,10 @@
                 if (!number.Negative && !positive && allowTrailingSign)
                 {
                     number.Negative |= reader.Read(negativeSign);
-                    positive |= reader.Read(positiveSign);
-                    Theraot.No.Op(positive);
+                    if (!number.Negative)
+                    {
+                        reader.Read(positiveSign);
+                    }
                 }
                 if (waitingParentheses && !reader.Read(')'))
                 {


Added confirmation page

Added confirmation page

--- GoldenTicket/Views/Registration/Confirmation.cshtml
+++ GoldenTicket/Views/Registration/Confirmation.cshtml
@@ -1,4 +1,6 @@
-
+@model GoldenTicket.Models.Applicant
+
+
 @{
     ViewBag.BodyId = "";
     ViewBag.BodyClass = "no-js success";
@@ -7,8 +9,12 @@

Success!

-
You’ve successfully entered {{First_name}} {{Last_name}} into the state-wide lottery for pre-kindergarten enrollment. If selected, you will be notified via phone  on August 16th.

-        Enroll another family member
+
+
You’ve successfully entered @Model.StudentFirstName @Model.StudentLastName into the state-wide lottery for pre-kindergarten enrollment. If selected, you will be notified via phone  on @ViewBag.NotificationDate

+
+
Your confirmation number is @Model.ConfirmationCode. If you have any questions, please contact Franklin Brito at 401-222-8184.

+
+        @Html.ActionLink("Enroll another family member", "StudentInformation")


Fixed typeo in what command line arguments are looked for

--- tools/settingsUtils.cake
+++ tools/settingsUtils.cake
@@ -30,7 +30,7 @@
 		obj.ExecutePackage 		= !GetBoolArgument(context, "skipPackage", !obj.ExecutePackage);

 		obj.ExecuteUnitTest 	= GetBoolArgument(context, "unitTest", obj.ExecuteUnitTest);
-		obj.ExecuteUnitTest 	= !GetBoolArgument(context, "unitTest", !obj.ExecuteUnitTest);
+		obj.ExecuteUnitTest 	= !GetBoolArgument(context, "skipUnitTest", !obj.ExecuteUnitTest);

 		obj.ExecuteClean 		= GetBoolArgument(context, "clean", obj.ExecuteClean);
 		obj.ExecuteClean 		= !GetBoolArgument(context, "skipClean", !obj.ExecuteClean);


Fix incorrect save value with translated label.

When label is translated in XML saved translated tag name.

--- RdlDesign/StyleTextCtl.cs
+++ RdlDesign/StyleTextCtl.cs
@@ -711,7 +711,7 @@
 			if (cbValue.Enabled)
 			{
 				if (fValue)
-					_Draw.SetElement(node, lblValue.Text, cbValue.Text);		// only adjust value when single item selected
+					_Draw.SetElement(node, "Value", cbValue.Text);		// only adjust value when single item selected
 			}

 			XmlNode sNode = _Draw.GetNamedChildNode(node, "Style");


marshal gsize as IntPtr to handle 64bit machines properly, fixes #332454

2006-02-28  Larry Ewing  <lewing@novell.com>

	* src/PixbufUtils.cs: marshal gsize as IntPtr to handle 64bit
	machines properly, fixes #332454

--- src/PixbufUtils.cs
+++ src/PixbufUtils.cs
@@ -265,7 +265,8 @@
 	}

 	[DllImport("libgdk_pixbuf-2.0-0.dll")]
-	static extern bool gdk_pixbuf_save_to_bufferv (IntPtr raw, out IntPtr data, out uint length, string type,
+	static extern bool gdk_pixbuf_save_to_bufferv (IntPtr raw, out IntPtr data, out IntPtr length,
+						       string type,
 						       string [] keys, string [] values, out IntPtr error);

@@ -273,7 +274,7 @@
 	{
 		IntPtr error = IntPtr.Zero;
 		IntPtr data;
-		uint length;
+		IntPtr length;
 		string [] terminated_options = null;
 		string [] terminated_values = null;

@@ -301,7 +302,7 @@
 		if (!success)
 			throw new ApplicationException ("Unknown error while saving file");

-		byte [] content = new byte [length];
+		byte [] content = new byte [(int)length];
 		Marshal.Copy (data, content, 0, (int)length);

 		return content;


Updated to latest Gum.

Updated to latest Gum.

--- Dodgeball/Dodgeball/GumCore/StandardElementsManager.cs
+++ Dodgeball/Dodgeball/GumCore/StandardElementsManager.cs
@@ -319,8 +319,7 @@

             AddPositioningVariables(stateSave);

-            stateSave.Variables.Add(new VariableSave { SetsValue = true, Type = "float", Value = 16.0f, Name = "Width" });
-            stateSave.Variables.Add(new VariableSave { SetsValue = true, Type = "float", Value = 16.0f, Name = "Height" });
+            AddDimensionsVariables(stateSave, 16, 16, DimensionVariableAction.ExcludeFileOptions);

             stateSave.Variables.Add(new VariableSave { SetsValue = true, Type = "bool", Value = true, Name = "Visible" });
             //AddColorVariables(stateSave, true);


+Test to exercise the Attribute instance property

--- src/ArguMint/ArguMint.UnitTests/MarkedPropertyTest.cs
+++ src/ArguMint/ArguMint.UnitTests/MarkedPropertyTest.cs
@@ -44,5 +44,21 @@

          Assert.AreEqual( propertyName, markedProperty.PropertyName );
       }
+
+      [TestMethod]
+      public void Attribute_HasValidAttribute_ReturnsInstanceProperly()
+      {
+         var attribute = new DontCareAttribute();
+
+         // Setup
+
+         var propertyInfo = typeof( MarkedPropertyTest ).GetProperty( "DummyProperty", BindingFlags.NonPublic | BindingFlags.Instance );
+
+         // Test
+
+         var markedProperty = new MarkedProperty<DontCareAttribute>( propertyInfo, attribute );
+
+         Assert.AreEqual( attribute, markedProperty.Attribute );
+      }
    }
 }


Fixed missing implmentation in ReverseDocComparatorSource.GetComparator() method.

--- src/BoboBrowse.Net/Sort/ReverseDocComparatorSource.cs
+++ src/BoboBrowse.Net/Sort/ReverseDocComparatorSource.cs
@@ -19,7 +19,7 @@

         public override DocComparator GetComparator(IndexReader reader, int docbase)
         {
-            throw new NotImplementedException();
+            return new ReverseDocComparator(_inner.GetComparator(reader, docbase));
         }

         public class ReverseDocComparator : DocComparator


Add one more test

Add one more test

--- tests/Paket.Bootstrapper.Tests/ArgumentParserTests.cs
+++ tests/Paket.Bootstrapper.Tests/ArgumentParserTests.cs
@@ -338,5 +338,30 @@
             Assert.That(result.DownloadArguments.MaxFileAgeInMinutes, Is.EqualTo(720));
             Assert.That(result.DownloadArguments.Target, Does.StartWith(Path.GetTempPath()).And.EndsWith(".exe"));
         }
+
+        [Test]
+        public void Magic_WithRun()
+        {
+            //arrange
+
+            //act
+            var result = ArgumentParser.ParseArgumentsAndConfigurations(
+                new[]
+                {
+                    ArgumentParser.CommandArgs.Silent,
+                    ArgumentParser.CommandArgs.Run,
+                    "-s",
+                    "--help",
+                    "foo"
+                }, null, null, false);
+
+            //assert
+            Assert.That(result.Run, Is.True);
+            Assert.That(result.Silent, Is.True);
+            Assert.That(result.RunArgs, Is.Not.Empty.And.EqualTo(new[] {"-s", "--help", "foo"}));
+            Assert.That(result.UnprocessedCommandArgs, Is.Empty);
+            Assert.That(result.DownloadArguments.Target, Does.StartWith(Path.GetTempPath()).And.EndsWith(".exe"));
+            Assert.That(result.DownloadArguments.MaxFileAgeInMinutes, Is.Null);
+        }
     }
 }


Updating DataServicePackageRepository to share PackageDownloader on clone

--HG--
branch : 1.5
extra : rebase_source : a1cd9dd5a350f1a639cc644d3d44f6af6ee4670c

--- src/Core/Repositories/DataServicePackageRepository.cs
+++ src/Core/Repositories/DataServicePackageRepository.cs
@@ -35,15 +35,22 @@
             : this(new HttpClient(serviceRoot)) {
         }

-        public DataServicePackageRepository(IHttpClient client) {
+        public DataServicePackageRepository(IHttpClient client)
+            : this(client, new PackageDownloader()) {
+        }
+
+        public DataServicePackageRepository(IHttpClient client, PackageDownloader packageDownloader) {
             if (client == null) {
                 throw new ArgumentNullException("client");
+            }
+            if (packageDownloader == null) {
+                throw new ArgumentNullException("packageDownloader");
             }

             _httpClient = client;
             _httpClient.AcceptCompression = true;

-            _packageDownloader = new PackageDownloader();
+            _packageDownloader = packageDownloader;
         }

         public override string Source {
@@ -113,7 +120,7 @@
         }

         public IPackageRepository Clone() {
-            return new DataServicePackageRepository(_httpClient);
+            return new DataServicePackageRepository(_httpClient, _packageDownloader);
         }

         private static string Escape(string value) {


Leave DD running after the watchdog test

--- tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs
+++ tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs
@@ -39,6 +39,8 @@
 			await RunBasicTest(cancellationToken);
 			await RunLongRunningTestThenUpdate(cancellationToken);
 			await RunLongRunningTestThenUpdateWithByondVersionSwitch(cancellationToken);
+
+			await StartAndLeaveRunning(cancellationToken);
 		}

 		async Task RunBasicTest(CancellationToken cancellationToken)
@@ -125,7 +127,7 @@

 			var daemonStatus = await DeployTestDme(DmeName, DreamDaemonSecurity.Safe, cancellationToken);

-			await WaitForJob(startJob, 10, false, cancellationToken);
+			await WaitForJob(startJob, 40, false, cancellationToken);

 			Assert.IsTrue(daemonStatus.Running.Value);
 			Assert.IsNotNull(daemonStatus.ActiveCompileJob);
@@ -146,6 +148,13 @@
 			Assert.IsFalse(daemonStatus.Running.Value);
 		}

+		async Task StartAndLeaveRunning(CancellationToken cancellationToken)
+		{
+			var startJob = await instanceClient.DreamDaemon.Start(cancellationToken).ConfigureAwait(false);
+
+			await WaitForJob(startJob, 40, false, cancellationToken);
+		}
+
 		async Task TellWorldToReboot(CancellationToken cancellationToken)
 		{
 			//we've wired long_running_test to reboot if its reboot mode is changed TO normal


fixes backspace when white space entry

fixes backspace when white space entry

--- src/FlubuCore/Infrastructure/Terminal/FlubuConsole.cs
+++ src/FlubuCore/Infrastructure/Terminal/FlubuConsole.cs
@@ -428,6 +428,12 @@
             }

             var splitedUserInput = userInput.Split(' ').Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
+            if (splitedUserInput.Count == 0)
+            {
+                _suggestionsForUserInput = null;
+                return;
+            }
+
             var targetName = splitedUserInput.First();
             var lastInput = splitedUserInput.Last();
             char prefix = lastInput[0];


Link to SelectedRepository not ActiveRepo

--- src/GitHub.App/ViewModels/PullRequestListViewModel.cs
+++ src/GitHub.App/ViewModels/PullRequestListViewModel.cs
@@ -114,7 +114,7 @@

             OpenPROnGitHub = new RelayCommand(x =>
             {
-                var repo = serviceProvider.TryGetService<ITeamExplorerServiceHolder>()?.ActiveRepo;
+                var repo = SelectedRepository;
                 var browser = serviceProvider.TryGetService<IVisualStudioBrowser>();
                 Debug.Assert(repo != null, "No active repo, cannot open PR on GitHub");
                 Debug.Assert(browser != null, "No browser service, cannot open PR on GitHub");


Reset loaded flag each time PR list is initialized.

--- src/GitHub.App/ViewModels/PullRequestListViewModel.cs
+++ src/GitHub.App/ViewModels/PullRequestListViewModel.cs
@@ -98,6 +98,8 @@
         {
             base.Initialize(data);

+            pullRequestsLoaded = false;
+
             PullRequests = repositoryHost.ModelService.GetPullRequests(repository, pullRequests);
             pullRequests.Subscribe(pr =>
             {


Updating log message

Updating log message

--- src/GitHub.App/ViewModels/PullRequestListViewModel.cs
+++ src/GitHub.App/ViewModels/PullRequestListViewModel.cs
@@ -117,7 +117,7 @@
                 .ObserveOn(RxApp.MainThreadScheduler)
                 .Catch<System.Reactive.Unit, Octokit.AuthorizationException>(ex =>
                 {
-                    log.Error(ex, "Error Processing PullRequests");
+                    log.Error(ex, "Authorization error listing pull requests");
                     return repositoryHost.LogOut();
                 })
                 .Catch<System.Reactive.Unit, Octokit.NotFoundException>(ex =>


Use the correct disposed object name (#13871)

The name of the disposed object should be FileBufferingWriteStream instead of FileBufferingReadStream

--- src/Http/WebUtilities/src/FileBufferingWriteStream.cs
+++ src/Http/WebUtilities/src/FileBufferingWriteStream.cs
@@ -238,7 +238,7 @@
         {
             if (Disposed)
             {
-                throw new ObjectDisposedException(nameof(FileBufferingReadStream));
+                throw new ObjectDisposedException(nameof(FileBufferingWriteStream));
             }
         }


remove note

remove note

--- src/Umbraco.Infrastructure/BackOffice/BackOfficeUserStore.cs
+++ src/Umbraco.Infrastructure/BackOffice/BackOfficeUserStore.cs
@@ -244,7 +244,6 @@
             if (string.IsNullOrEmpty(passwordHash)) throw new ArgumentException("Value can't be empty.", nameof(passwordHash));

             user.PasswordHash = passwordHash;
-            // TODO: Need to set the user.PasswordConfig based on what the current configuration is

             return Task.CompletedTask;
         }


Possible fix for test db issue

Possible fix for test db issue

Signed-off-by: Bjarke Berg <1d6e1cf70ec6f9ab28d3ea4b27a49a77654d370e@bergmania.dk>

--- src/Umbraco.Tests.Integration/Testing/LocalDbTestDatabase.cs
+++ src/Umbraco.Tests.Integration/Testing/LocalDbTestDatabase.cs
@@ -66,11 +66,11 @@
             // there's probably a sweet spot to be found for size / parallel...

             var s = ConfigurationManager.AppSettings["Umbraco.Tests.LocalDbTestDatabase.EmptyPoolSize"];
-            var emptySize = s == null ? 2 : int.Parse(s);
+            var emptySize = s == null ? 1 : int.Parse(s);
             s = ConfigurationManager.AppSettings["Umbraco.Tests.LocalDbTestDatabase.EmptyPoolThreadCount"];
             var emptyParallel = s == null ? 1 : int.Parse(s);
             s = ConfigurationManager.AppSettings["Umbraco.Tests.LocalDbTestDatabase.SchemaPoolSize"];
-            var schemaSize = s == null ? 2 : int.Parse(s);
+            var schemaSize = s == null ? 1 : int.Parse(s);
             s = ConfigurationManager.AppSettings["Umbraco.Tests.LocalDbTestDatabase.SchemaPoolThreadCount"];
             var schemaParallel = s == null ? 1 : int.Parse(s);

@@ -347,7 +347,9 @@
                         }

                         if (!_readyQueue.IsAddingCompleted)
+                        {
                             _readyQueue.Add(i);
+                        }
                     }
                 });
             }


All the things button respects log setting

--- src/Unicorn/ControlPanel/Controls/BatchProcessingControls.cs
+++ src/Unicorn/ControlPanel/Controls/BatchProcessingControls.cs
@@ -7,7 +7,7 @@
 	{
 		public void Render(HtmlTextWriter writer)
 		{
-			writer.Write($@"
{new HeadingService().GetAllTheThings()} Sync all the things!
");
+			writer.Write($@"
{new HeadingService().GetAllTheThings()} Sync all the things!
");

 			writer.Write(@"


Formatting some code

Formatting some code

--- src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Styles.cs
+++ src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Styles.cs
@@ -490,18 +490,17 @@
             }
         }

-
         public static Texture2D BranchIcon
         {
-          get
-          {
-            if (branchIcon == null)
-            {
-              branchIcon = Utility.GetIcon("branch.png", "branch@2x.png");
-            }
-
-            return branchIcon;
-          }
+            get
+            {
+                if (branchIcon == null)
+                {
+                    branchIcon = Utility.GetIcon("branch.png", "branch@2x.png");
+                }
+
+                return branchIcon;
+            }
         }

         public static Texture2D TrackingBranchIcon


Renaming variable

Renaming variable

--- src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Styles.cs
+++ src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Styles.cs
@@ -831,16 +831,16 @@
             }
         }

-        private static Texture2D rootFolderIcon;
+        private static Texture2D globeIcon;
         public static Texture2D GlobeIcon
         {
             get
             {
-                if (rootFolderIcon == null)
-                {
-                    rootFolderIcon = Utility.GetIcon("globe.png", "globe@2x.png");
-                }
-                return rootFolderIcon;
+                if (globeIcon == null)
+                {
+                    globeIcon = Utility.GetIcon("globe.png", "globe@2x.png");
+                }
+                return globeIcon;
             }
         }


テナント管理、サービス管理の権限のビット位置を変更。

テナント管理、サービス管理の権限のビット位置を変更。


update

update

--- Infrastructure/CSharpGL.Models/Cube/CubeRenderer.cs
+++ Infrastructure/CSharpGL.Models/Cube/CubeRenderer.cs
@@ -7,6 +7,7 @@
 namespace CSharpGL
 {
     /// <summary>
+    /// Render a Cube with single color in modern opengl.
     /// </summary>
     public class CubeRenderer : PickableRenderer
     {


ストリームに表示する最大ポスト数を設定する機能を追加。

ストリームに表示する最大ポスト数を設定する機能を追加。

1.MaxActivitiesCountプロパティを追加
このプロパティへ代入された数だけポストをVMのActivitiesに入れるようにした。

--- GPlusBrowser/ViewModel/Stream/CircleStreamViewModel.cs
+++ GPlusBrowser/ViewModel/Stream/CircleStreamViewModel.cs
@@ -18,10 +18,23 @@
             Activities = new DispatchObservableCollection<ActivityViewModel>(uiThreadDispatcher);
             Order = order;
             Circle = circle;
+            MaxActivitiesCount = 40;
         }
+        int _maxActivityCount;
         Stream _circle;
         DispatchObservableCollection<ActivityViewModel> _activities;

+        public int MaxActivitiesCount
+        {
+            get { return _maxActivityCount; }
+            set
+            {
+                _maxActivityCount = value;
+                OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("MaxActivitiesCount"));
+                lock (_activities)
+                    ActivitiesCompaction(value);
+            }
+        }
         public Stream Circle
         {
             get { return _circle; }
@@ -60,30 +73,53 @@
         protected void OnActivitiesCollectionChanged(
             object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
         {
-            switch (e.Action)
+            lock (Activities)
             {
-                case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
-                    for (var i = 0; i < e.NewItems.Count; i++)
-                    {
-                        var viewModel = new ActivityViewModel((Activity)e.NewItems[i], UiThreadDispatcher);
-                        if(Activities.Count - (e.NewStartingIndex + i) >= 0)
+                switch (e.Action)
+                {
+                    case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
+                        for (var i = e.NewItems.Count - 1; i >= 0; i--)
                         {
-                            Activities.Insert(Math.Max(0, Activities.Count - (e.NewStartingIndex + i)), viewModel);
+                            var viewModel = new ActivityViewModel((Activity)e.NewItems[i], UiThreadDispatcher);
+                            var idx = _circle.Activities.Count - (e.NewStartingIndex + i) - 1;
+                            if (idx >= 0 && idx < MaxActivitiesCount - 1)
+                                Activities.Insert(idx, viewModel);
                         }
-                        else
+                        break;
+                    case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
+                        for (var i = 0; i < e.OldItems.Count; i++)
                         {
-                            if (System.Diagnostics.Debugger.IsAttached)
-                                System.Diagnostics.Debugger.Break();
+                            var idx = _circle.Activities.Count - (e.OldStartingIndex) - 1;
+                            if (idx >= 0 && idx < MaxActivitiesCount - 1)
+                            {
+                                Activities[idx].Dispose();
+                                Activities.RemoveAt(idx);
+                            }
                         }
-                    }
-                    break;
-                case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
-                    for (var i = 0; i < e.OldItems.Count; i++)
-                        Activities.RemoveAt(Activities.Count - (e.OldStartingIndex) - 1);
-                    break;
-                case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
-                    Activities.Clear();
-                    break;
+                        break;
+                    case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
+                        for (var i = 0; i < Activities.Count; i++)
+                            Activities[i].Dispose();
+                        Activities.Clear();
+                        break;
+                }
+                ActivitiesCompaction(MaxActivitiesCount);
+            }
+        }
+        void ActivitiesCompaction(int ActivitiesCapacity)
+        {
+            if (Activities.Count > ActivitiesCapacity)
+            {
+                for (var i = ActivitiesCapacity; i < Activities.Count; i++)
+                {
+                    Activities[i].Dispose();
+                    Activities.RemoveAt(i);
+                }
+            }
+            else
+            {
+                for (var i = _circle.Activities.Count - Activities.Count - 1; i >= 0 && i < _circle.Activities.Count; i++)
+                    Activities.Add(new ActivityViewModel(_circle.Activities[i], UiThreadDispatcher));
             }
         }
     }


NetworkChannel包头BUG修复

NetworkChannel包头BUG修复

--- GameFramework/Network/NetworkManager.NetworkChannel.cs
+++ GameFramework/Network/NetworkManager.NetworkChannel.cs
@@ -655,7 +655,7 @@
                     m_Socket = null;
                 }

-                if (packetHeaderLength != 1 || packetHeaderLength != 2 || packetHeaderLength != 4)
+                if (packetHeaderLength != 1 && packetHeaderLength != 2 && packetHeaderLength != 4)
                 {
                     throw new GameFrameworkException("Packet header length is invalid, you can only use 1, 2 or 4.");
                 }