Reduce deferred renderer enumerator allocations

--- src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
+++ src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
@@ -355,15 +355,19 @@

                     node.BeginRender(context, isLayerRoot);

-                    foreach (var operation in node.DrawOperations)
-                    {
+                    var drawOperations = node.DrawOperations;
+                    for (int i = 0; i < drawOperations.Count; i++)
+                    {
+                        var operation = drawOperations[i];
                         _currentDraw = operation;
                         operation.Item.Render(context);
                         _currentDraw = null;
                     }

-                    foreach (var child in node.Children)
-                    {
+                    var children = node.Children;
+                    for (int i = 0; i < children.Count; i++)
+                    {
+                        var child = children[i];
                         Render(context, (VisualNode)child, layer, clipBounds);
                     }


ProcessMethodInvocation should be overridable

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@2272 2c1201b4-01cd-e047-a400-b836ae1fbc61

--- src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
+++ src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
@@ -3821,7 +3821,7 @@
 			}
 		}

-		private void ProcessMethodInvocation(MethodInvocationExpression node, IEntity targetEntity)
+		protected virtual void ProcessMethodInvocation(MethodInvocationExpression node, IEntity targetEntity)
 		{
 			IMethod targetMethod = (IMethod)targetEntity;
 			if (!CheckParameters(targetMethod.CallableType, node.Arguments, false))


Operator "isa" now also works with structs. There is no reason to forbid this.

--- src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
+++ src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
@@ -4842,7 +4842,7 @@

 		void BindTypeTest(BinaryExpression node)
 		{
-			if (CheckIsNotValueType(node, node.Left) && CheckIsaArgument(node.Right))
+			if (CheckIsaArgument(node.Right))
 				BindExpressionType(node, TypeSystemServices.BoolType);
 			else
 				Error(node);


Added testing to writing words, not just writing bytes

--- CSharpZorkMachine/Program.cs
+++ CSharpZorkMachine/Program.cs
@@ -27,8 +27,9 @@
             GameMemory gameState = new GameMemory(immutablePart, changingPart);

             WordAddress zeroPointer = new WordAddress(0);
-            IEnumerable<WordAddress> firstFivePointers = Enumerable.Range(0, 5)
-                .Select(el => zeroPointer + el);
+            List<WordAddress> firstFivePointers = Enumerable.Range(0, 5)
+                .Select(el => zeroPointer + el)
+                .ToList();

             IEnumerable<ByteAddress> firstTenByteAddress = Enumerable.Range(0, 10)
                 .Select(el => new ByteAddress(el));
@@ -68,10 +69,25 @@
                 .Select(p => gameState.ReadAddress(p))
                 .ToArray();

-            string mutated = new string(Encoding.UTF8.GetChars(firstTenBytesAgain));
+            string mutated = new string(Encoding.UTF8.GetChars(firstTenBytesAgain));

+            //test writing Words instead of bytes to game state:
+            byte[] toWriteWordWise = Encoding.UTF8.GetBytes("aaZZeess33");
+            WordAddress zero = new WordAddress(0);
+            for(int i = 0; i < toWriteWordWise.Length - 1; i += 2)
+            {
+                int val = (toWriteWordWise[i] * 256 + toWriteWordWise[i + 1]);
+                WordAddress address = zero + i / 2;
+                gameState.WriteWord(address, new Word(val));
+            }
+
+            byte[] firstTenBytesAgain2 = firstTenByteAddress
+                .Select(p => gameState.ReadAddress(p))
+                .ToArray();

-            Console.WriteLine($"{whatIRead} became {mutated}");
+            string mutated2 = new string(Encoding.UTF8.GetChars(firstTenBytesAgain2));
+
+            Console.WriteLine($"{whatIRead} became {mutated} and then {mutated2}");

         }


Remove DrumHit.

Remove DrumHit.

--- osu.Game.Modes.Taiko/Objects/DrumHit.cs
+++ osu.Game.Modes.Taiko/Objects/DrumHit.cs
@@ -1,15 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace osu.Game.Modes.Taiko.Objects
-{
-    class DrumHit
-    {
-    }
-}


fix a bad error message

fix a bad error message

--- Jil/Deserialize/InlineDeserializer.cs
+++ Jil/Deserialize/InlineDeserializer.cs
@@ -21,8 +21,7 @@
         public static bool UseNameAutomataSwitches = true;
         public static bool UseNameAutomataBinarySearch = true;
         public static bool UseFastRFC1123Method = true;
-        //public static bool UseFastUnionLookup = true;
-        public static bool UseFastUnionLookup = false;
+        public static bool UseFastUnionLookup = true;

         const string CharBufferName = "char_buffer";
         const string StringBuilderName = "string_builder";
@@ -232,6 +231,12 @@
             Emit.LoadConstant(false);                                   // string TextReader bool
             ThrowStringStreamBool();                                    // DeserializationException
             Emit.Throw();                                               // --empty--
+        }
+
+        void ThrowExpected(char[] cs)
+        {
+            var ps = cs.Cast<object>().ToArray();
+            ThrowExpected(ps);
         }

         void ExpectChar(char c)


Fix ETag tests.

Fix ETag tests.

--- src/Cassette.UnitTests/Web/ModuleRequestHandler.cs
+++ src/Cassette.UnitTests/Web/ModuleRequestHandler.cs
@@ -72,127 +72,127 @@
                 requestContext
             );
         }
-
-        public class GivenModuleExists_WhenProcessRequest : ModuleRequestHandler_Tests
-        {
-            public GivenModuleExists_WhenProcessRequest()
-            {
-                var module = new Module("~/test") { ContentType = "expected-content-type" };
-                var asset = new Mock<IAsset>();
-                asset.Setup(a => a.OpenStream())
-                     .Returns(() => "asset-content".AsStream());
-                asset.SetupGet(a => a.Hash).Returns(new byte[] { 1, 2, 3 });
-                module.Assets.Add(asset.Object);
-                container.Setup(c => c.FindModuleContainingPath("~\\test"))
-                         .Returns(module);
-
-                var handler = CreateRequestHandler("test");
-                handler.ProcessRequest();
-            }
-
-            readonly DateTime start = DateTime.UtcNow;
-
-            [Fact]
-            public void ModuleAssetContentReturned()
-            {
-                outputStream.Position = 0;
-                outputStream.ReadToEnd().ShouldEqual("asset-content");
-            }
-
-            [Fact]
-            public void ContentTypeIsTheModuleContentType()
-            {
-                response.VerifySet(r => r.ContentType = "expected-content-type");
-            }
-
-            [Fact]
-            public void ExpiresInOneYear()
-            {
-                responseCache.Verify(c => c.SetExpires(It.Is<DateTime>(d => (d - start).TotalDays >= 365)));
-            }
-
-            [Fact]
-            public void ResponseIsPubliclyCacheable()
-            {
-                responseCache.Verify(c => c.SetCacheability(HttpCacheability.Public));
-            }
-
-            [Fact]
-            public void ETagIsAssetHash()
-            {
-                var expectedETag = "010203";
-                responseCache.Verify(c => c.SetETag(expectedETag));
-            }
-        }
-
-        public class GivenModuleDoesNotExist : ModuleRequestHandler_Tests
-        {
-            [Fact]
-            public void HandlerReturns404()
-            {
-                var handler = CreateRequestHandler("scripts/unknown-module");
-
-                handler.ProcessRequest();
-
-                response.VerifySet(r => r.StatusCode = 404);
-            }
-        }
-
-        public class GivenModuleExistsAndIfNonMatchHeaderIsEqualAssetHash_WhenProcessRequest : ModuleRequestHandler_Tests
-        {
-            public GivenModuleExistsAndIfNonMatchHeaderIsEqualAssetHash_WhenProcessRequest()
-            {
-                var module = new Module("~/test");
-                var asset = new Mock<IAsset>();
-                asset.Setup(a => a.OpenStream())
-                     .Returns(() => "asset-content".AsStream());
-                asset.SetupGet(a => a.Hash).Returns(new byte[] { 1, 2, 3 });
-                module.Assets.Add(asset.Object);
-                container.Setup(c => c.FindModuleContainingPath("~\\test"))
-                         .Returns(module);
-
-                requestHeaders["If-None-Match"] = "010203";
-                var handler = CreateRequestHandler("test");
-                handler.ProcessRequest();
-            }
-
-            [Fact]
-            public void StatusCodeIs304NotModified()
-            {
-                response.VerifySet(r => r.StatusCode = 304);
-            }
-        }
-
-        public class GivenModuleExistsAndIfNonMatchHeaderIsNotEqualAssetHash_WhenProcessRequest : ModuleRequestHandler_Tests
-        {
-            public GivenModuleExistsAndIfNonMatchHeaderIsNotEqualAssetHash_WhenProcessRequest()
-            {
-                var module = new Module("~/test");
-                var asset = new Mock<IAsset>();
-                asset.Setup(a => a.OpenStream())
-                     .Returns(() => "asset-content".AsStream());
-                asset.SetupGet(a => a.Hash).Returns(new byte[] { 1, 2, 3 });
-                module.Assets.Add(asset.Object);
-                container.Setup(c => c.FindModuleContainingPath("~\\test"))
-                         .Returns(module);
-
-                requestHeaders["If-None-Match"] = "xxxxxx";
-                var handler = CreateRequestHandler("test");
-                handler.ProcessRequest();
-            }
-
-            [Fact]
-            public void ModuleAssetContentReturned()
-            {
-                outputStream.Position = 0;
-                (outputStream.Length > 0).ShouldBeTrue();
-            }
-        }
-
         void IDisposable.Dispose()
         {
             outputStream.Dispose();
         }
     }
+
+    public class GivenModuleExists_WhenProcessRequest : ModuleRequestHandler_Tests
+    {
+        public GivenModuleExists_WhenProcessRequest()
+        {
+            var module = new Module("~/test") { ContentType = "expected-content-type" };
+            var asset = new Mock<IAsset>();
+            asset.Setup(a => a.OpenStream())
+                    .Returns(() => "asset-content".AsStream());
+            asset.SetupGet(a => a.Hash).Returns(new byte[] { 1, 2, 3 });
+            module.Assets.Add(asset.Object);
+            container.Setup(c => c.FindModuleContainingPath("~\\test"))
+                        .Returns(module);
+
+            var handler = CreateRequestHandler("test");
+            handler.ProcessRequest();
+        }
+
+        readonly DateTime start = DateTime.UtcNow;
+
+        [Fact]
+        public void ModuleAssetContentReturned()
+        {
+            outputStream.Position = 0;
+            outputStream.ReadToEnd().ShouldEqual("asset-content");
+        }
+
+        [Fact]
+        public void ContentTypeIsTheModuleContentType()
+        {
+            response.VerifySet(r => r.ContentType = "expected-content-type");
+        }
+
+        [Fact]
+        public void ExpiresInOneYear()
+        {
+            responseCache.Verify(c => c.SetExpires(It.Is<DateTime>(d => (d - start).TotalDays >= 365)));
+        }
+
+        [Fact]
+        public void ResponseIsPubliclyCacheable()
+        {
+            responseCache.Verify(c => c.SetCacheability(HttpCacheability.Public));
+        }
+
+        [Fact]
+        public void ETagIsAssetHash()
+        {
+            var expectedETag = "\"010203\"";
+            responseCache.Verify(c => c.SetETag(expectedETag));
+        }
+    }
+
+    public class GivenModuleDoesNotExist : ModuleRequestHandler_Tests
+    {
+        [Fact]
+        public void HandlerReturns404()
+        {
+            var handler = CreateRequestHandler("scripts/unknown-module");
+
+            handler.ProcessRequest();
+
+            response.VerifySet(r => r.StatusCode = 404);
+        }
+    }
+
+    public class GivenModuleExistsAndIfNonMatchHeaderIsEqualAssetHash_WhenProcessRequest : ModuleRequestHandler_Tests
+    {
+        public GivenModuleExistsAndIfNonMatchHeaderIsEqualAssetHash_WhenProcessRequest()
+        {
+            var module = new Module("~/test");
+            var asset = new Mock<IAsset>();
+            asset.Setup(a => a.OpenStream())
+                    .Returns(() => "asset-content".AsStream());
+            asset.SetupGet(a => a.Hash).Returns(new byte[] { 1, 2, 3 });
+            module.Assets.Add(asset.Object);
+            container.Setup(c => c.FindModuleContainingPath("~\\test"))
+                        .Returns(module);
+
+            requestHeaders["If-None-Match"] = "\"010203\"";
+            var handler = CreateRequestHandler("test");
+            handler.ProcessRequest();
+        }
+
+        [Fact]
+        public void StatusCodeIs304NotModified()
+        {
+            response.VerifySet(r => r.StatusCode = 304);
+        }
+    }
+
+    public class GivenModuleExistsAndIfNonMatchHeaderIsNotEqualAssetHash_WhenProcessRequest : ModuleRequestHandler_Tests
+    {
+        public GivenModuleExistsAndIfNonMatchHeaderIsNotEqualAssetHash_WhenProcessRequest()
+        {
+            var module = new Module("~/test");
+            var asset = new Mock<IAsset>();
+            asset.Setup(a => a.OpenStream())
+                    .Returns(() => "asset-content".AsStream());
+            asset.SetupGet(a => a.Hash).Returns(new byte[] { 1, 2, 3 });
+            module.Assets.Add(asset.Object);
+            container.Setup(c => c.FindModuleContainingPath("~\\test"))
+                        .Returns(module);
+
+            requestHeaders["If-None-Match"] = "xxxxxx";
+            var handler = CreateRequestHandler("test");
+            handler.ProcessRequest();
+        }
+
+        [Fact]
+        public void ModuleAssetContentReturned()
+        {
+            outputStream.Position = 0;
+            (outputStream.Length > 0).ShouldBeTrue();
+        }
+    }
+
 }


Simplify lookup fallback code

Simplify lookup fallback code

--- osu.Game.Tournament/IPC/FileBasedIPC.cs
+++ osu.Game.Tournament/IPC/FileBasedIPC.cs
@@ -4,7 +4,6 @@
 using System;
 using System.IO;
 using System.Linq;
-using System.Collections.Generic;
 using JetBrains.Annotations;
 using Microsoft.Win32;
 using osu.Framework.Allocation;
@@ -187,32 +186,13 @@
         [CanBeNull]
         private string findStablePath()
         {
-            string stableInstallPath = string.Empty;
-
-            try
-            {
-                List<Func<string>> stableFindMethods = new List<Func<string>>
-                {
-                    findFromEnvVar,
-                    findFromRegistry,
-                    findFromLocalAppData,
-                    findFromDotFolder
-                };
-
-                foreach (var r in stableFindMethods)
-                {
-                    stableInstallPath = r.Invoke();
-
-                    if (stableInstallPath != null)
-                        return stableInstallPath;
-                }
-
-                return null;
-            }
-            finally
-            {
-                Logger.Log($"Stable path for tourney usage: {stableInstallPath}");
-            }
+            var stableInstallPath = findFromEnvVar() ??
+                                    findFromRegistry() ??
+                                    findFromLocalAppData() ??
+                                    findFromDotFolder();
+
+            Logger.Log($"Stable path for tourney usage: {stableInstallPath}");
+            return stableInstallPath;
         }

         private string findFromEnvVar()


hardcode defaults in ui

hardcode defaults in ui

--- CameraSlidersUC/CSUC.xaml.cs
+++ CameraSlidersUC/CSUC.xaml.cs
@@ -148,6 +148,9 @@
                     new[]{ RC_Brigh_Lvl, RC_Cont_Lvl, RC_Exp_Lvl, RC_Gain_Lvl, RC_Sat_Lvl, RC_WBT_Lvl, RC_Foc_Lvl },
                     new[]{ MC3_Brigh_Lvl, MC3_Cont_Lvl, MC3_Exp_Lvl, MC3_Gain_Lvl, MC3_Sat_Lvl, MC3_WBT_Lvl, MC3_Foc_Lvl },
                     new[]{ MC4_Brigh_Lvl, MC4_Cont_Lvl, MC4_Exp_Lvl, MC4_Gain_Lvl, MC4_Sat_Lvl, MC4_WBT_Lvl, MC4_Foc_Lvl}};
+
+                    int[] defaults = new int[] {128, 33, 100, 64, 32, 5315, 16};
+
                     string[] info = new[] { "camera0", "camera1", "camera2", "camera3" };
                     //end setup

@@ -178,6 +181,7 @@
                             Dispatcher.Invoke(new Action(() =>
                             {
                                 SUBS[i][j] = new SliderStuff(node, j, info[i], sliders[i][j], labels[i][j], new Action<int>(fire));
+                                SUBS[i][j].Value = defaults[j];
                             }));
                         }
                     }


remove debug code

remove debug code

--- Jil/Deserialize/InlineDeserializer.cs
+++ Jil/Deserialize/InlineDeserializer.cs
@@ -504,14 +504,7 @@
             // We also must confirm that we read everything, again otherwise we might accept garbage as valid
             ExpectEndOfStream();

-            try
-            {
-                Emit.Return();
-            }
-            catch (Sigil.SigilVerificationException e)
-            {
-                Console.Write(e);
-            }
+            Emit.Return();

             return Emit.CreateDelegate<Func<TextReader, int, ForType>>();
         }


manual fixup

manual fixup

--- src/Compilers/Core/MSBuildTaskTests/TargetTests.cs
+++ src/Compilers/Core/MSBuildTaskTests/TargetTests.cs
@@ -1,8 +1,8 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
+
 // uncomment the below define to dump binlogs of each test
-
 //#define DUMP_MSBUILD_BIN_LOG

 using System;


Code tidying.

Code tidying.

--- osu.Game/Graphics/Cursor/CursorTrail.cs
+++ osu.Game/Graphics/Cursor/CursorTrail.cs
@@ -56,6 +56,8 @@

         const int MAX_SPRITES = 2048;

+        Vector2? lastPosition;
+
         protected override DrawNode CreateDrawNode() => new TrailDrawNode();

         protected override void ApplyDrawNode(DrawNode node)
@@ -65,43 +67,6 @@
             TrailDrawNode tNode = node as TrailDrawNode;
             tNode.Shader = shader;
             tNode.Time = time;
-        }
-
-        Vector2? last;
-
-        protected override bool OnMouseMove(InputState state)
-        {
-            if (last == null)
-            {
-                last = state.Mouse.Position;
-                return base.OnMouseMove(state);
-            }
-
-            Vector2 pos1 = last.Value;
-            Vector2 pos2 = state.Mouse.Position;
-
-            Vector2 diff = (pos2 - pos1);
-            float distance = diff.Length;
-            Vector2 direction = diff / distance;
-
-            float interval = this[0].DrawSize.X / 2;
-
-            for (float d = interval; d < distance; d += interval)
-            {
-                last = pos1 + direction * d;
-                addPosition(last.Value);
-            }
-
-            return base.OnMouseMove(state);
-        }
-
-        private void addPosition(Vector2 pos)
-        {
-            var s = this[currentIndex];
-            s.Position = pos;
-            s.Alpha = time + 1f;
-
-            currentIndex = (currentIndex + 1) % MAX_SPRITES;
         }

         public CursorTrail()
@@ -140,9 +105,44 @@
             timeOffset = Time.Current;
         }

+        protected override bool OnMouseMove(InputState state)
+        {
+            if (lastPosition == null)
+            {
+                lastPosition = state.Mouse.Position;
+                return base.OnMouseMove(state);
+            }
+
+            Vector2 pos1 = lastPosition.Value;
+            Vector2 pos2 = state.Mouse.Position;
+
+            Vector2 diff = pos2 - pos1;
+            float distance = diff.Length;
+            Vector2 direction = diff / distance;
+
+            float interval = this[0].DrawSize.X / 2;
+
+            for (float d = interval; d < distance; d += interval)
+            {
+                lastPosition = pos1 + direction * d;
+                addPosition(lastPosition.Value);
+            }
+
+            return base.OnMouseMove(state);
+        }
+
+        private void addPosition(Vector2 pos)
+        {
+            var s = this[currentIndex];
+            s.Position = pos;
+            s.Alpha = time + 1f;
+
+            currentIndex = (currentIndex + 1) % MAX_SPRITES;
+        }
+
         class TrailDrawNode : ContainerDrawNode
         {
-            public Shader Shader;
+            public new Shader Shader;
             public float Time;

             public override void Draw(IVertexBatch vertexBatch)


Use ReadSkipWhitespace() in trivial cases

ConsumeWhiteSpace + ExpectChar becomes ReadSkipWhitespace + CheckChar

--- Jil/Deserialize/InlineDeserializer.cs
+++ Jil/Deserialize/InlineDeserializer.cs
@@ -141,13 +141,29 @@
             ThrowExpected(c);                       // --empty--

             Emit.MarkLabel(gotChar);                // --empty--
-        }
-
-        void ExpectQuote()
-        {
-            ExpectChar('"');
-        }
-
+        }
+
+        void CheckChar(char c)
+        {
+            var gotChar = Emit.DefineLabel();
+
+            Emit.LoadConstant((int)c);              // int int
+            Emit.BranchIfEqual(gotChar);            // --empty--
+            ThrowExpected(c);                       // --empty--
+
+            Emit.MarkLabel(gotChar);                // --empty--
+        }
+
+        void ExpectQuote()
+        {
+            ExpectChar('"');
+        }
+
+        void CheckQuote()
+        {
+            CheckChar('"');
+        }
+
         void ExpectRawCharOrNull(char c, Action ifChar, Action ifNull)
         {
             var gotChar = Emit.DefineLabel();
@@ -481,8 +497,14 @@
         {
             Emit.LoadArgument(0);                   // TextReader
             Emit.Call(Methods.ConsumeWhiteSpace);       // --empty--
-        }
-
+        }
+
+        void ReadSkipWhitespace()
+        {
+            Emit.LoadArgument(0);                   // TextReader
+            Emit.Call(Methods.ReadSkipWhitespace);  // int
+        }
+
         void ExpectEndOfStream()
         {
             var success = Emit.DefineLabel();
@@ -824,8 +846,8 @@
                         Build(keyType);         // dictType(*?) enum
                     }
                 }
-                ConsumeWhiteSpace();        // dictType(*?) (integer|string|enum)
-                ExpectChar(':');            // dictType(*?) (integer|string|enum)
+                ReadSkipWhitespace();        // dictType(*?) (integer|string|enum)
+                CheckChar(':');            // dictType(*?) (integer|string|enum)
                 ConsumeWhiteSpace();        // dictType(*?) (integer|string|enum)
                 Build(valType);             // dictType(*?) (integer|string|enum) valType
                 Emit.CallVirtual(addMtd);   // --empty--
@@ -867,9 +889,9 @@
                     {
                         Build(keyType);         // dictType(*?) enum
                     }
-                }
-                ConsumeWhiteSpace();                // dictType(*?) (integer|string|enum)
-                ExpectChar(':');                    // dictType(*?) (integer|string|enum)
+                }
+                ReadSkipWhitespace();               // dictType(*?) (integer|string|enum)
+                CheckChar(':');                     // dictType(*?) (integer|string|enum)
                 ConsumeWhiteSpace();                // dictType(*?) (integer|string|enum)
                 Build(valType);                     // dictType(*?) (integer|string|enum) valType
                 Emit.CallVirtual(addMtd);           // --empty--
@@ -934,8 +956,8 @@

             Emit.LoadArgument(0);                   // objType TextReader
             Emit.Call(Methods.SkipEncodedString);   // objType
-            ConsumeWhiteSpace();                    // objType
-            ExpectChar(':');                        // objType
+            ReadSkipWhitespace();                   // objType
+            CheckChar(':');                         // objType
             ConsumeWhiteSpace();                    // objType
             SkipObjectMember();                     // objType
             Emit.Branch(continueSkipping);          // objType
@@ -953,8 +975,8 @@
             ConsumeWhiteSpace();                    // objType
             Emit.LoadArgument(0);                   // objType TextReader
             Emit.Call(Methods.SkipEncodedString);   // objType
-            ConsumeWhiteSpace();                    // objType
-            ExpectChar(':');                        // objType
+            ReadSkipWhitespace();                   // objType
+            CheckChar(':');                         // objType
             ConsumeWhiteSpace();                    // objType
             SkipObjectMember();                     // objType
             Emit.Branch(continueSkipping);          // objType
@@ -1050,14 +1072,14 @@
                 RawPeekChar();              // objType(*?) int
                 Emit.LoadConstant('}');     // objType(*?) int '}'
                 Emit.BranchIfEqual(done);   // objType(*?)
-                ConsumeWhiteSpace();        // objType(*?)
-
-                ExpectQuote();              // objType(*?)
+                ReadSkipWhitespace();       // objType(*?)
+
+                CheckQuote();               // objType(*?)
                 Emit.LoadArgument(0);       // objType(*?) TextReader
                 Emit.Call(findSetterIdx);  // objType(*?) int

-                ConsumeWhiteSpace();        // objType(*?) int
-                ExpectChar(':');            // objType(*?) int
+                ReadSkipWhitespace();        // objType(*?) int
+                CheckChar(':');            // objType(*?) int
                 ConsumeWhiteSpace();        // objType(*?) int

                 var readingMember = Emit.DefineLabel();
@@ -1125,14 +1147,14 @@
                 Emit.LoadArgument(0);               // objType(*?) TextReader
                 Emit.CallVirtual(TextReader_Read);  // objType(*?) int
                 Emit.Pop();                         // objType(*?)
-                ConsumeWhiteSpace();
-
-                ExpectQuote();
+                ReadSkipWhitespace();
+
+                CheckQuote();
                 Emit.LoadArgument(0);           // TextReader
                 Emit.Call(findSetterIdx);      // int

-                ConsumeWhiteSpace();                // objType(*?) int
-                ExpectChar(':');                    // objType(*?) int
+                ReadSkipWhitespace();               // objType(*?) int
+                CheckChar(':');                     // objType(*?) int
                 ConsumeWhiteSpace();                // objType(*?) int
                 Emit.Branch(readingMember);         // objType(*?) int
             }
@@ -1229,9 +1251,9 @@
                 Emit.LoadConstant('}');     // objType(*?) int '}'
                 Emit.BranchIfEqual(done);   // objType(*?)
                 Emit.LoadField(order);      // objType(*?) Dictionary<string, int> string
-                Build(typeof(string));      // obType(*?) Dictionary<string, int> string
-                ConsumeWhiteSpace();        // objType(*?) Dictionary<string, int> string
-                ExpectChar(':');            // objType(*?) Dictionary<string, int> string
+                Build(typeof(string));      // obType(*?) Dictionary<string, int> string
+                ReadSkipWhitespace();       // objType(*?) Dictionary<string, int> string
+                CheckChar(':');             // objType(*?) Dictionary<string, int> string
                 ConsumeWhiteSpace();        // objType(*?) Dictionary<string, int> string

                 var readingMember = Emit.DefineLabel();
@@ -1300,9 +1322,9 @@
                 Emit.Pop();                         // objType(*?)
                 ConsumeWhiteSpace();
                 Emit.LoadField(order);              // objType(*?) Dictionary<string, int> string
-                Build(typeof(string));              // objType(*?) Dictionary<string, int> string
-                ConsumeWhiteSpace();                // objType(*?) Dictionary<string, int> string
-                ExpectChar(':');                    // objType(*?) Dictionary<string, int> string
+                Build(typeof(string));              // objType(*?) Dictionary<string, int> string
+                ReadSkipWhitespace();               // objType(*?) Dictionary<string, int> string
+                CheckChar(':');                     // objType(*?) Dictionary<string, int> string
                 ConsumeWhiteSpace();                // objType(*?) Dictionary<string, int> string
                 Emit.Branch(readingMember);         // objType(*?) Dictionary<string, int> string
             }
@@ -1379,9 +1401,9 @@
             Emit.LoadConstant('}');     // int '}'
             Emit.BranchIfEqual(doneNotNull);   // --empty--
             Emit.LoadField(order);      // Dictionary<string, int> string
-            Build(typeof(string));      // Dictionary<string, int> string
-            ConsumeWhiteSpace();        // Dictionary<string, int> string
-            ExpectChar(':');            // Dictionary<string, int> string
+            Build(typeof(string));      // Dictionary<string, int> string
+            ReadSkipWhitespace();       // Dictionary<string, int> string
+            CheckChar(':');             // Dictionary<string, int> string
             ConsumeWhiteSpace();        // Dictionary<string, int> string

             var readingMember = Emit.DefineLabel();
@@ -1440,9 +1462,9 @@
             Emit.Pop();                         // --empty--
             ConsumeWhiteSpace();                // --empty--
             Emit.LoadField(order);              // Dictionary<string, int> string
-            Build(typeof(string));              // Dictionary<string, int> string
-            ConsumeWhiteSpace();                // Dictionary<string, int> string
-            ExpectChar(':');                    // Dictionary<string, int> string
+            Build(typeof(string));              // Dictionary<string, int> string
+            ReadSkipWhitespace();               // Dictionary<string, int> string
+            CheckChar(':');                     // Dictionary<string, int> string
             ConsumeWhiteSpace();                // Dictionary<string, int> string
             Emit.Branch(readingMember);         // Dictionary<string, int> string

@@ -1541,8 +1563,8 @@
             Emit.LoadArgument(0);                       // TextReader
             Emit.Call(findConstructorParameterIndex);   // int

-            ConsumeWhiteSpace();        // int
-            ExpectChar(':');            // int
+            ReadSkipWhitespace();       // int
+            CheckChar(':');             // int
             ConsumeWhiteSpace();        // int

             var readingMember = Emit.DefineLabel();
@@ -1583,14 +1605,14 @@
             Emit.LoadArgument(0);               // TextReader
             Emit.CallVirtual(TextReader_Read);  // int
             Emit.Pop();                         // --empty--
-            ConsumeWhiteSpace();                // --empty--
-
-            ExpectQuote();                              // --empty--
+            ReadSkipWhitespace();               // --empty--
+
+            CheckQuote();                               // --empty--
             Emit.LoadArgument(0);                       // TextReader
             Emit.Call(findConstructorParameterIndex);   // int

-            ConsumeWhiteSpace();                // int
-            ExpectChar(':');                    // int
+            ReadSkipWhitespace();               // int
+            CheckChar(':');                     // int
             ConsumeWhiteSpace();                // int
             Emit.Branch(readingMember);         // int


Follow web design more.

Follow web design more.

--- osu.Game/Users/Profile/ProfileHeader.cs
+++ osu.Game/Users/Profile/ProfileHeader.cs
@@ -6,6 +6,7 @@
 using OpenTK.Graphics;
 using osu.Framework.Extensions.Color4Extensions;
 using osu.Framework.Graphics;
+using osu.Framework.Graphics.Colour;
 using osu.Framework.Graphics.Containers;
 using osu.Framework.Graphics.Sprites;
 using osu.Game.Graphics;
@@ -20,12 +21,12 @@

         private readonly OsuTextFlowContainer infoText;

-        private const float cover_height = 200, avatar_size = 110, avatar_bottom_position = -20;
+        private const float cover_height = 350, info_height = 150, avatar_size = 110, avatar_bottom_position = -20, level_position = 30, level_height = 60;
         public ProfileHeader(User user)
         {
             this.user = user;
             RelativeSizeAxes = Axes.X;
-            Height = cover_height + cover_height - UserProfile.TAB_HEIGHT;
+            Height = cover_height + info_height - UserProfile.TAB_HEIGHT;

             Children = new Drawable[]
             {
@@ -45,6 +46,11 @@
                         {
                             Masking = true,
                             RelativeSizeAxes = Axes.Both
+                        },
+                        new Box
+                        {
+                            RelativeSizeAxes = Axes.Both,
+                            ColourInfo = ColourInfo.GradientVertical(Color4.Black.Opacity(0.1f), Color4.Black.Opacity(0.75f))
                         },
                         new UpdateableAvatar
                         {
@@ -101,8 +107,63 @@
                     Margin = new MarginPadding { Horizontal = UserProfile.CONTENT_X_MARGIN },
                     RelativeSizeAxes = Axes.X,
                     AutoSizeAxes = Axes.Y,
-                    ParagraphSpacing = 1,
-                    //LineSpacing = 0.5f
+                    ParagraphSpacing = 1
+                },
+                new Container
+                {
+                    X = -UserProfile.CONTENT_X_MARGIN,
+                    RelativeSizeAxes = Axes.Y,
+                    Width = 280,
+                    Anchor = Anchor.TopRight,
+                    Origin = Anchor.TopRight,
+                    Children = new Drawable[]
+                    {
+                        new Container
+                        {
+                            RelativeSizeAxes = Axes.X,
+                            Y = level_position,
+                            Height = level_height,
+                            Children = new Drawable[]
+                            {
+                                new Box
+                                {
+                                    Colour = Color4.Black.Opacity(0.5f),
+                                    RelativeSizeAxes = Axes.Both
+                                }
+                            }
+                        },
+                        new Container
+                        {
+                            RelativeSizeAxes = Axes.X,
+                            Y = cover_height,
+                            Anchor = Anchor.TopCentre,
+                            Origin = Anchor.BottomCentre,
+                            Height = cover_height - level_height - level_position - 5,
+                            Children = new Drawable[]
+                            {
+                                new Box
+                                {
+                                    Colour = Color4.Black.Opacity(0.5f),
+                                    RelativeSizeAxes = Axes.Both
+                                }
+                            }
+                        },
+                        new Container
+                        {
+                            RelativeSizeAxes = Axes.X,
+                            Anchor = Anchor.BottomCentre,
+                            Origin = Anchor.BottomCentre,
+                            Height = info_height - UserProfile.TAB_HEIGHT - 15,
+                            Children = new Drawable[]
+                            {
+                                new Box
+                                {
+                                    Colour = Color4.Black.Opacity(0.25f),
+                                    RelativeSizeAxes = Axes.Both
+                                }
+                            }
+                        }
+                    }
                 }
             };


Update BoxDecorator.cs

Update BoxDecorator.cs

--- src/Core2D/Editor/Tools/Decorators/BoxDecorator.cs
+++ src/Core2D/Editor/Tools/Decorators/BoxDecorator.cs
@@ -548,7 +548,23 @@
                     break;
                 case Mode.Bottom:
                     {
-                        _groupBox.ScaleBottom(dy, _points);
+                        if (isProportionalResize)
+                        {
+                            var width = _groupBox.Bounds.Width;
+                            var height = _groupBox.Bounds.Height;
+                            var ratioHeight = (height + dy) / height;
+
+                            dx = (width * ratioHeight) - width;
+
+                            _groupBox.ScaleLeft(-dx / 2.0, _points);
+                            _groupBox.ScaleRight(dx / 2.0, _points);
+
+                            _groupBox.ScaleBottom(dy, _points);
+                        }
+                        else
+                        {
+                            _groupBox.ScaleBottom(dy, _points);
+                        }
                     }
                     break;
                 case Mode.Left:


Allow sealed method from Object

Allow sealed method from Object

--- src/Cormo/Impl/Weld/Utils/InterceptionValidator.cs
+++ src/Cormo/Impl/Weld/Utils/InterceptionValidator.cs
@@ -23,7 +23,7 @@
                     .SelectMany(x => new[] { x.SetMethod, x.GetGetMethod() }.Where(m => m != null)))
                 .Where(x=> !x.IsPrivate).ToArray();

-            var nonVirtualMethods = methods.Where(x => !TypeUtils.IsOveridable(x)).ToArray();
+            var nonVirtualMethods = methods.Where(x => !TypeUtils.IsOveridable(x) && x.DeclaringType != typeof(object)).ToArray();
             if (nonVirtualMethods.Any())
             {
                 if (allowPartial)


Related to #118

Related to #118

--- src/DbLocalizationProvider/LocalizationProvider.cs
+++ src/DbLocalizationProvider/LocalizationProvider.cs
@@ -1,4 +1,4 @@
-// Copyright © 2017 Valdis Iljuconoks.
+// Copyright (c) 2018 Valdis Iljuconoks.
 // Permission is hereby granted, free of charge, to any person
 // obtaining a copy of this software and associated documentation
 // files (the "Software"), to deal in the Software without
@@ -34,7 +34,7 @@
     /// </summary>
     public class LocalizationProvider
     {
-        private static readonly Lazy<LocalizationProvider> Instance = new Lazy<LocalizationProvider>(() =>
+        private static Lazy<LocalizationProvider> Instance = new Lazy<LocalizationProvider>(() =>
             new LocalizationProvider(ConfigurationContext.Current.EnableInvariantCultureFallback));

         private readonly bool _fallbackEnabled;
@@ -45,9 +45,17 @@
         }

         /// <summary>
-        /// Access to current instance of the provider. This property can be used in IoC containers to support dependency injection.
+        ///     Access to current instance of the provider. This property can be used in IoC containers to support dependency
+        ///     injection.
         /// </summary>
-        public static LocalizationProvider Current => Instance.Value;
+        public static LocalizationProvider Current
+        {
+            get => Instance.Value;
+            set
+            {
+                Instance = new Lazy<LocalizationProvider>(() => value);
+            }
+        }

         /// <summary>
         /// Gets translation for the resource with specific key.


Fix NRE on missing asset unit name

Fix NRE on missing asset unit name

--- LSLib/Granny/Model/ColladaImporter.cs
+++ LSLib/Granny/Model/ColladaImporter.cs
@@ -132,13 +132,15 @@

             if (collada.asset != null)
             {
-                if (collada.asset.unit.name == "meter")
-                    toolInfo.UnitsPerMeter = (float)collada.asset.unit.meter;
-                else if (collada.asset.unit.name == "centimeter")
-                    toolInfo.UnitsPerMeter = (float)collada.asset.unit.meter * 100;
-                else
-                    throw new NotImplementedException("Unsupported asset unit type: " + collada.asset.unit.name);
-
+                if (collada.asset.unit != null)
+                {
+                    if (collada.asset.unit.name == "meter")
+                        toolInfo.UnitsPerMeter = (float)collada.asset.unit.meter;
+                    else if (collada.asset.unit.name == "centimeter")
+                        toolInfo.UnitsPerMeter = (float)collada.asset.unit.meter * 100;
+                    else
+                        throw new NotImplementedException("Unsupported asset unit type: " + collada.asset.unit.name);
+                }

                 if (collada.asset.contributor != null && collada.asset.contributor.Length > 0)
                 {


Add one more missing CLI rename

Add one more missing CLI rename

--- src/DotVVM.CommandLine/OpenApi/ApiClientManager.cs
+++ src/DotVVM.CommandLine/OpenApi/ApiClientManager.cs
@@ -81,9 +81,9 @@
                 });

             var resolver = new CSharpTypeResolver(settings.CSharpGeneratorSettings);
-            var generator = new DotvvmSwaggerToCSharpClientGenerator(document, settings, resolver);
+            var generator = new DotvvmCSharpClientGenerator(document, settings, resolver);
             var csharp = generator.GenerateFile();
-
+
             if (definition.GenerateWrapperClass && !definition.IsSingleClient)
             {
                 csharp = ApiClientUtils.InjectWrapperClass(csharp, className, clientNames);


dotvvm configuration.json.tmp is dumped always when Debug == true

--- src/DotVVM.Framework/Hosting/VisualStudioHelper.cs
+++ src/DotVVM.Framework/Hosting/VisualStudioHelper.cs
@@ -9,11 +9,11 @@
     {
         public static void DumpConfiguration(DotvvmConfiguration config, string directory)
         {
-            if (Process.GetCurrentProcess().ProcessName == "iisexpress")
+            if (config.Debug || Process.GetCurrentProcess().ProcessName == "iisexpress")
             {
                 try
                 {
-                    File.WriteAllText(Path.Combine(directory, "dotvvm_serialized_config.json.tmp"), JsonConvert.SerializeObject(config));
+                    File.WriteAllText(Path.Combine(directory, "dotvvm_serialized_config.json.tmp"), JsonConvert.SerializeObject(config, Formatting.Indented));
                 }
                 catch
                 {


Revert "convert TODO to issue #134"

Revert "convert TODO to issue #134"

This reverts commit 99f679a016f3492c2af9191cb041385c0f4eab4d.

--- src/FilterLists.Api/Controllers/ListsController.cs
+++ src/FilterLists.Api/Controllers/ListsController.cs
@@ -3,6 +3,8 @@

 namespace FilterLists.Api.Controllers
 {
+    //TODO: migrate controllers to separate projects by version, use dependency injection
+    //TODO: automate URL versioning
     [Route("v1/[controller]")]
     [Produces("application/json")]
     public class ListsController : Controller


async AddOrUpdateRules()

async AddOrUpdateRules()

--- src/FilterLists.Services/Services/ScrapeService.cs
+++ src/FilterLists.Services/Services/ScrapeService.cs
@@ -25,7 +25,7 @@
         {
             var lists = await GetNextFilterListsToScrape(batchSize);
             var snapshots = await GetSnapshots(lists);
-            snapshots.ForEach(AddOrUpdateRules);
+            snapshots.ForEach(async snapshot => await AddOrUpdateRules(snapshot));
         }

         private async Task<IEnumerable<FilterListViewUrlDto>> GetNextFilterListsToScrape(int batchSize)
@@ -66,7 +66,7 @@
             return null;
         }

-        private void AddOrUpdateRules(Snapshot snapshot)
+        private async Task AddOrUpdateRules(Snapshot snapshot)
         {
             // add new Rules
             var preExistingSnapshotRules = dbContext.Rules.Where(x => snapshot.RawRules.Contains(x.Raw));
@@ -96,7 +96,7 @@
             list.ScrapedDateUtc = DateTime.UtcNow;
             dbContext.FilterLists.Update(list);

-            dbContext.SaveChanges();
+            await dbContext.SaveChangesAsync();
         }

         private class FilterListViewUrlDto


Added a test for the RecursiveNodeFilter that asserts that the proper Node state is getting copied into FilteredNode objects.

--- src/FluentSiteMap.Test/RecursiveNodeFilterTests.cs
+++ src/FluentSiteMap.Test/RecursiveNodeFilterTests.cs
@@ -43,6 +43,46 @@
         }

         [Test]
+        public void Filter_should_copy_state_from_nodes_to_filtered_nodes()
+        {
+            var filter = MockRepository.GenerateStub<INodeFilter>();
+            filter
+                .Stub(
+                    f =>
+                    f.Filter(Arg<FilteredNode>.Is.Anything,
+                             Arg<FilterContext>.Is.Anything))
+                .Return(true);
+
+            _rootNode = new Node(new[] {filter})
+                            {
+                                Title = "title",
+                                Description = "description",
+                                Url = "/url",
+                                Target = "_target"
+                            };
+            _rootNode.Metadata["key1"] = "value1";
+            _rootNode.Metadata["key2"] = "value2";
+
+            IRecursiveNodeFilter target = new RecursiveNodeFilter();
+
+            var result = target.Filter(_context, _rootNode);
+
+            Assert.That(result, ContainsState.With(
+                new
+                    {
+                        Title = "title",
+                        Description = "description",
+                        Url = "/url",
+                        Target = "_target",
+                        Metadata = new Dictionary<string, object>
+                                       {
+                                           {"key1", "value1"},
+                                           {"key2", "value2"}
+                                       }
+                    }));
+        }
+
+        [Test]
         public void Filter_should_filter_nodes_with_both_the_default_filters_and_the_node_filters()
         {
             var filter1 = MockRepository.GenerateMock<INodeFilter>();


changed encoding

changed encoding

--- src/GalileoAgentNet/Internal/CollectorConnector.cs
+++ src/GalileoAgentNet/Internal/CollectorConnector.cs
@@ -87,7 +87,7 @@
             switch (requestCompression)
             {
                 case CollectorRequestCompression.PlainText:
-                    content = new StringContent(jsonRequestBody, Encoding.Default);
+                    content = new StringContent(jsonRequestBody, Encoding.UTF8);
                     break;

                 case CollectorRequestCompression.GZip:


add removeFromAddingResources flag

add removeFromAddingResources flag

--- SS.Integration.Adapter/StreamListenerManager.cs
+++ SS.Integration.Adapter/StreamListenerManager.cs
@@ -187,6 +187,7 @@

         public virtual void CreateStreamListener(IResourceFacade resource, IAdapterPlugin platformConnector)
         {
+            bool removeFromAddingResources = false;
             try
             {
                 _logger.InfoFormat("Attempting to create a Listener for sport={0} and {1}", resource.Sport, resource);
@@ -203,6 +204,7 @@
                     _logger.InfoFormat("Enother creation of listener processing right now for {0}, skipping creation", resource);
                     return;
                 }
+                removeFromAddingResources = true;

                 var listener = CreateStreamListenerObject(resource, platformConnector, EventState, StateManager);

@@ -233,8 +235,12 @@
             }
             finally
             {
-                bool v;
-                _addingResources.TryRemove(resource.Id, out v);
+                if (removeFromAddingResources)
+                {
+                    bool v;
+                    _addingResources.TryRemove(resource.Id, out v);
+                }
+
                 MarkResourceAsProcessable(resource);

                 SaveEventState();


- v3.5.0

- v3.5.0

--- Shuttle.ESB.RabbitMQ/Properties/AssemblyInfo.cs
+++ Shuttle.ESB.RabbitMQ/Properties/AssemblyInfo.cs
@@ -18,11 +18,11 @@
 [assembly: AssemblyTitle("Shuttle.ESB.RabbitMQ for .NET Framework 4.5.2")]
 #endif

-[assembly: AssemblyVersion("3.4.5.0")]
+[assembly: AssemblyVersion("3.5.0.0")]
 [assembly: AssemblyCopyright("Copyright © Eben Roux 2010-2015")]
 [assembly: AssemblyProduct("Shuttle.ESB")]
 [assembly: AssemblyCompany("Shuttle")]
 [assembly: AssemblyConfiguration("Release")]
-[assembly: AssemblyInformationalVersion("3.4.5")]
+[assembly: AssemblyInformationalVersion("3.5.0")]
 [assembly: ComVisible(false)]


proveedor

proveedor

(TFS CS 3944)

--- Signum.Entities.Extensions/Basics/DateSpanDN.cs
+++ Signum.Entities.Extensions/Basics/DateSpanDN.cs
@@ -3,6 +3,7 @@
 using System.Linq;
 using System.Text;
 using Signum.Utilities;
+using System.Linq.Expressions;

 namespace Signum.Entities.Extensions.Basics
 {
@@ -10,7 +11,7 @@
     public class DateSpanDN : EmbeddedEntity
     {
         int years;
-        [LocDescription ]
+        [LocDescription]
         public int Years
         {
             get { return years; }
@@ -35,21 +36,32 @@

         public bool EsNulo()
         {
-            return years == 0 && months == 0 && days == 0;
+            return years == 0 && months == 0 && days == 0;
         }

-        public DateTime Add(DateTime date)
+        //static Expression<Func<DateSpanDN, DateTime>> MethodExpression =
+        //     (ds, dt) => dt.AddYears(ds.Years).AddMonths(ds.Months).AddDays(ds.Days);
+        //public DateTime Add(DateTime date)
+        //{
+        //    return date.AddYears(years).AddMonths(months).AddDays(days);
+        //}
+
+
+        static Expression<Func<DateSpanDN,DateTime, DateTime>> AddExpression =
+             (ds, dt) => dt.AddYears(ds.Years).AddMonths(ds.Months).AddDays(ds.Days);
+        static Func<DateSpanDN,DateTime, DateTime> AddFunc = AddExpression.Compile();
+        public  DateTime Add( DateTime date)
         {
-            return date.AddYears(years).AddMonths(months).AddDays(days);
+            return AddFunc(this, date);
         }

         public DateSpan ToDateSpan()
         {
-            return new DateSpan(years, months, days);
+            return new DateSpan(years, months, days);
         }
         public override string ToString()
         {
             return ToDateSpan().ToString();
-        }
+        }
     }
 }


Support both acom and functions github auth requests

--- SimpleWAWS/Authentication/GitHubAuthProvider.cs
+++ SimpleWAWS/Authentication/GitHubAuthProvider.cs
@@ -41,7 +41,7 @@
                 return TokenResults.DoesntExist;
             }

-            var user = GetUserFromGraph(code);
+            var user = GetUserFromGraph(code, context);

             if (user == null)
             {
@@ -51,15 +51,28 @@
             return TokenResults.ExistsAndCorrect;
         }

-        private IPrincipal GetUserFromGraph(string accessToken)
+        private IPrincipal GetUserFromGraph(string code, HttpContextBase context)
         {
-            //treat the provided github code as the access_token
-            if (string.IsNullOrEmpty(accessToken))
+            bool acomAuthRequest = context.Request.QueryString["referer"] == "acom";
+            var githubAccessToken = new GitHubAccessTokenResponse();
+
+            if (!acomAuthRequest)
             {
-                return null;
+                // treat code a regular code
+                var githubAccessTokenResponse = AuthUtilities.GetContentFromGitHubUrl(GetGraphUrl(code, context), "POST",
+                    jsonAccept: true);
+
+                    githubAccessToken =
+                    JsonConvert.DeserializeObject<GitHubAccessTokenResponse>(githubAccessTokenResponse);
+
+                if (string.IsNullOrEmpty(githubAccessToken.AccessToken))
+                {
+                    return null;
+                }
             }
+
             //Now get user's emailid
-            var githubUserEmailsResponse = AuthUtilities.GetContentFromGitHubUrl(GetGitHubUserUrl(), addGitHubHeaders: true, AuthorizationHeader: GetGitHubAuthHeader(accessToken));
+            var githubUserEmailsResponse = AuthUtilities.GetContentFromGitHubUrl(GetGitHubUserUrl(), addGitHubHeaders: true, AuthorizationHeader: GetGitHubAuthHeader(acomAuthRequest? code: githubAccessToken.AccessToken));
             var githubUserEmails = JsonConvert.DeserializeObject<IList<GitHubUserEmailResponse>>(githubUserEmailsResponse);
             var primaryEmail = githubUserEmails.FirstOrDefault(em => em.Primary && em.Verified);
             if (primaryEmail == null)
@@ -79,7 +92,28 @@
             return "https://api.github.com/user/emails";
         }

+        private string GetGraphUrl(string code, HttpContextBase context)
+        {
+            var builder = new StringBuilder();
+            builder.Append("https://github.com/login/oauth/access_token");
+            builder.AppendFormat("?client_id={0}", AuthSettings.GitHubClientId);
+            builder.AppendFormat("&client_secret={0}", AuthSettings.GitHubClientSecret);
+            builder.AppendFormat("&code={0}", code);
+            builder.AppendFormat("&redirect_uri={0}", WebUtility.UrlEncode(string.Format(CultureInfo.InvariantCulture, "https://{0}/", context.Request.Headers["HOST"], context.Request.Url.Query)));
+            return builder.ToString();
+        }

+        private class GitHubAccessTokenResponse
+        {
+            [JsonProperty("access_token")]
+            public string AccessToken { get; set; }
+
+            [JsonProperty("scope")]
+            public string Scope { get; set; }
+
+            [JsonProperty("token_type")]
+            public string TokenType { get; set; }
+        }
         private class GitHubUserEmailResponse
         {
             [JsonProperty("email")]


Fix overlap calculation for SortedSpans

Fix overlap calculation for SortedSpans

This in turn fixes span classification for selection over OutputBuffer in Interactive Window.
And provide correct color when copying error messages.

--- src/InteractiveWindow/Editor/Output/SortedSpans.cs
+++ src/InteractiveWindow/Editor/Output/SortedSpans.cs
@@ -50,19 +50,39 @@

             lock (_mutex)
             {
-                int startIndex = _spans.BinarySearch(span, comparer);
-                if (startIndex < 0)
-                {
-                    startIndex = ~startIndex - 1;
-                }
+                var count = _spans.Count;

-                if (startIndex < 0)
+                // _span is empty, no overlap.
+                if (count == 0)
                 {
                     return Enumerable.Empty<Span>();
                 }

+                int startIndex = _spans.BinarySearch(span, comparer);
+
+                // If span is not found in _span, BinarySearch returns a negative number that is the
+                // bitwise complement of the index of the next span with larger starting index, or if
+                // there is no such span, the bitwise complement of _span.Count.
+
+                // Try get next span in _span with larger starting index, in case the span starts
+                // before the first one in _span, e.g. span starts within the logo of interactive window.
+                // If there's truly no overlap, then the for-loop will stop before first iteration.
+                if (startIndex < 0)
+                {
+                    startIndex = ~startIndex;
+                }
+
+                // It still possible that the it overlaps with last span in _span,
+                // so we will only check the last one.
+                if (startIndex == count)
+                {
+                    startIndex = startIndex - 1;
+                }
+
+                Debug.Assert(startIndex >= 0);
+
                 int spanEnd = span.End;
-                for (int i = startIndex; i < _spans.Count && _spans[i].Start < spanEnd; i++)
+                for (int i = startIndex; i < count && _spans[i].Start < spanEnd; i++)
                 {
                     var overlap = span.Overlap(_spans[i]);
                     if (overlap.HasValue)


Optimised inserting into tables

Optimised inserting into tables

--- SlackHistoryViewer.RestoreFromLocal/Database.cs
+++ SlackHistoryViewer.RestoreFromLocal/Database.cs
@@ -6,7 +6,7 @@
 using SlackHistoryViewer.Database;
 using SlackHistoryViewer.Database.Models;
 using SlackHistoryViewer.Helpers;
-using SlackHistoryViewer.RestoreFromLocal.Configuration;
+using SlackHistoryViewer.Configuration;
 using SlackHistoryViewer.Slack.Models;

 namespace SlackHistoryViewer.RestoreFromLocal
@@ -17,25 +17,32 @@
         {
         }

-        public static void TruncateTable(string tableName)
+        public static void TruncateTables(params string[] tableNames)
         {
-            using (var dbContext = new SlackHistoryViewerDbContext(AppSettings.Instance.ConnectionString))
+            using (var dbContext = new SlackHistoryViewerDbContext())
             {
-                var sql = string.Format("DELETE FROM {0}", tableName);
-                dbContext.Database.ExecuteSqlCommand(sql);
+                var sql = string.Empty;

-                sql = string.Format("DBCC CHECKIDENT ({0}, RESEED, 0)", tableName);
-                dbContext.Database.ExecuteSqlCommand(sql);
+                foreach (var tableName in tableNames)
+                {
+                    sql = string.Format("DELETE FROM {0}", tableName);
+                    dbContext.Database.ExecuteSqlCommand(sql);
+
+                    sql = string.Format("DBCC CHECKIDENT ({0}, RESEED, 0)", tableName);
+                    dbContext.Database.ExecuteSqlCommand(sql);
+                }
             }
         }

         public static void InsertUsers(string path)
         {
-            using (var dbContext = new SlackHistoryViewerDbContext(AppSettings.Instance.ConnectionString))
+            using (var dbContext = new SlackHistoryViewerDbContext())
             {
                 var data = GetData<Member>(path, AppSettings.Instance.UsersFile);

                 dbContext.Users.AddRange(data.Select(u => new Users(u.Id, u.Name)));
+                dbContext.Users.Add(new Users(AppSettings.Instance.SlackBotId, AppSettings.Instance.SlackBotName));
+                dbContext.Users.Add(new Users(AppSettings.Instance.UnknownBotId, AppSettings.Instance.UnknownBotName));

                 dbContext.SaveChanges();
             }
@@ -43,7 +50,7 @@

         public static void InsertChannels(string path)
         {
-            using (var dbContext = new SlackHistoryViewerDbContext(AppSettings.Instance.ConnectionString))
+            using (var dbContext = new SlackHistoryViewerDbContext())
             {
                 var data = GetData<Channel>(path, AppSettings.Instance.ChannelsFile);

@@ -53,50 +60,45 @@
             }
         }

-        public static void AddMessage(Message message, string channelId)
+        public static void AddMessage(SlackHistoryViewerDbContext dbContext, Message message, string channelId)
         {
-            using (var dbContext = new SlackHistoryViewerDbContext(AppSettings.Instance.ConnectionString))
+            var newMessage = new Messages();
+            newMessage.MessageId = MD5Hasher.GetMd5Hash(message.User + message.TimeStamp);
+
+            var idUser = dbContext.Users.Where(u => u.UserId == message.User)
+                .Select(u => u.Id)
+                .FirstOrDefault();
+
+            if (idUser == 0)
             {
-                var newMessage = new Messages();
-                newMessage.MessageId = MD5Hasher.GetMd5Hash(message.User + message.TimeStamp);
-
-                var idUser = dbContext.Users.Where(u => u.UserId == message.User)
+                var botId = dbContext.Users.Where(u => u.UserId == AppSettings.Instance.UnknownBotId)
                     .Select(u => u.Id)
                     .FirstOrDefault();

-                if (idUser == null)
-                {
-                    var botId = dbContext.Users.Where(u => u.UserId == AppSettings.Instance.SlackBotId)
-                        .Select(u => u.Id)
-                        .FirstOrDefault();
+                idUser = botId;
+            }

-                    idUser = botId;
-                }
+            newMessage.UserId = idUser;

-                newMessage.UserId = idUser;
+            var idChannel = dbContext.Channels.Where(c => c.ChannelId == channelId)
+                .Select(c => c.Id)
+                .FirstOrDefault();

-                var idChannel = dbContext.Channels.Where(c => c.ChannelId == channelId)
-                    .Select(c => c.Id)
-                    .FirstOrDefault();
+            newMessage.ChannelId = idChannel;
+            newMessage.JsonData = JsonConvert.SerializeObject(message);

-                newMessage.ChannelId = idChannel;
-                newMessage.JsonData = JsonConvert.SerializeObject(message);
-
-                dbContext.Messages.Add(newMessage);
-
-                dbContext.SaveChanges();
-            }
+            dbContext.Messages.Add(newMessage);
         }

         public static void InsertMessages(string path)
         {
-            using (var dbContext = new SlackHistoryViewerDbContext(AppSettings.Instance.ConnectionString))
+            using (var dbContext = new SlackHistoryViewerDbContext())
             {
                 var files = Directory.GetFiles(@path, "*.*", SearchOption.AllDirectories);

                 foreach (string file in files)
                 {
-                    if (IsChannelsOrUsersFile(file))
+                    if (IsFileIgnored(file))
                     {
                         continue;
                     }
@@ -110,17 +112,31 @@
                     var text = File.ReadAllText(file);
                     var data = JsonConvert.DeserializeObject<List<Message>>(text);

-                    foreach (Message message in data)
+                    foreach (var message in data)
                     {
-                        AddMessage(message, channelId);
+                        if (IsAttachment(message))
+                        {
+                            continue;
+                        }
+
+                        AddMessage(dbContext, message, channelId);
                     }
+
+                    dbContext.SaveChanges();
                 }
             }
         }

-        private static bool IsChannelsOrUsersFile(string file)
+        private static bool IsAttachment(Message message)
         {
-            return file.EndsWith(AppSettings.Instance.UsersFile) || file.EndsWith(AppSettings.Instance.ChannelsFile);
+            return string.IsNullOrEmpty(message.Text) && message.Attachments.Any();
+        }
+
+        private static bool IsFileIgnored(string file)
+        {
+            return file.EndsWith(AppSettings.Instance.UsersFile) ||
+                file.EndsWith(AppSettings.Instance.ChannelsFile) ||
+                file.EndsWith(AppSettings.Instance.IntegrationLogsFile);
         }

         private static List<T> GetData<T>(string path, string filename)


Fixing the drop menu to hold the pencil on the left

issue #1279

--- SlicerConfiguration/SettingsControlSelectors.cs
+++ SlicerConfiguration/SettingsControlSelectors.cs
@@ -49,7 +49,7 @@
 	{
 		private Button editButton;
 		private NamedSettingsLayers layerType;
-		private DropDownList dropDownList;
+		GuiWidget pullDownContainer;

 		private int extruderIndex; //For multiple materials

@@ -87,14 +87,16 @@
 			};

 			this.AddChild(labelText);
-			this.AddChild(GetPulldownContainer());
+			pullDownContainer = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren);
+			pullDownContainer.AddChild(GetPulldownContainer());
+			this.AddChild(pullDownContainer);
 			this.AddChild(new VerticalSpacer());
 			this.AddChild(accentBar);
 		}

-		public virtual FlowLayoutWidget GetPulldownContainer()
-		{
-			dropDownList = CreateDropdown();
+		public FlowLayoutWidget GetPulldownContainer()
+		{
+			var dropDownList = CreateDropdown();

 			FlowLayoutWidget container = new FlowLayoutWidget();
 			container.HAnchor = HAnchor.ParentLeftRight;
@@ -209,18 +211,8 @@

 		private void RebuildDropDownList()
 		{
-			// TODO: Consider adding a .Replace(existingWidget, newWidget) to GuiWidget
-			// Replace existing list with updated list
-			var parent = this.dropDownList.Parent;
-
-			if (parent != null)
-			{
-				parent.RemoveChild(this.dropDownList);
-				this.dropDownList.Close();
-
-				this.dropDownList = CreateDropdown();
-				parent.AddChild(this.dropDownList);
-			}
+			pullDownContainer.CloseAllChildren();
+			pullDownContainer.AddChild(GetPulldownContainer());
 		}

 		private void MenuItem_Selected(object sender, EventArgs e)


updating legacy function for player melee skill (#2908)

* updating legacy function for player melee skill

* .

--- Source/ACE.Server/WorldObjects/Player_Combat.cs
+++ Source/ACE.Server/WorldObjects/Player_Combat.cs
@@ -65,27 +65,23 @@
         {
             var weapon = GetEquippedWeapon();

-            // missile weapon
-            if (weapon != null && weapon.CurrentWieldedLocation == EquipMask.MissileWeapon)
-                return GetCreatureSkill(Skill.MissileWeapons).Skill;
-
-            if (weapon != null && weapon.WeaponSkill == Skill.TwoHandedCombat)
-                return Skill.TwoHandedCombat;
-
-            // hack for converting pre-MoA skills
-            var maxMelee = GetCreatureSkill(GetHighestMeleeSkill());
+            if (weapon?.WeaponSkill == null)
+                return GetHighestMeleeSkill();
+
+            var skill = ConvertToMoASkill(weapon.WeaponSkill);

             // DualWieldAlternate will be TRUE if *next* attack is offhand
             if (IsDualWieldAttack && !DualWieldAlternate)
             {
+                var weaponSkill = GetCreatureSkill(skill);
                 var dualWield = GetCreatureSkill(Skill.DualWield);

                 // offhand attacks use the lower skill level between dual wield and weapon skill
-                if (dualWield.Current < maxMelee.Current)
-                    return dualWield.Skill;
-            }
-
-            return maxMelee.Skill;
+                if (dualWield.Current < weaponSkill.Current)
+                    skill = Skill.DualWield;
+            }
+            //Console.WriteLine($"{Name}.GetCurrentWeaponSkill - {skill}");
+            return skill;
         }

         /// <summary>


License info; text handling; object processing

--- Source/ContractsWindow.Unity/Unity/CW_Window.cs
+++ Source/ContractsWindow.Unity/Unity/CW_Window.cs
@@ -1,4 +1,30 @@
-using System;
+#region license
+/*The MIT License (MIT)
+CW_Window - Controls the main UI window
+
+Copyright (c) 2016 DMagic
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#endregion
+
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using ContractsWindow.Unity.Interfaces;
@@ -12,9 +38,9 @@
 	public class CW_Window : CanvasFader, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IScrollHandler
 	{
 		[SerializeField]
-		private Text VersionText = null;
-		[SerializeField]
-		private Text MissionTitle = null;
+		private TextHandler VersionText = null;
+		[SerializeField]
+		private TextHandler MissionTitle = null;
 		[SerializeField]
 		private Button MissionEdit = null;
 		[SerializeField]
@@ -124,7 +150,7 @@
 			windowInterface = window;

 			if (VersionText != null)
-				VersionText.text = window.Version;
+				VersionText.OnTextUpdate.Invoke(window.Version);

 			CreateMissionSections(window.GetMissions);

@@ -152,6 +178,8 @@

 			tooltips = GetComponentsInChildren<TooltipHandler>(true).ToList();

+			ToggleTooltips(windowInterface.HideTooltips);
+
 			UpdateFontSize(progressPanel.gameObject, windowInterface.LargeFont ? 1 : 0);
 		}

@@ -168,6 +196,8 @@
 			if (obj == null)
 				return;

+			progress.ProcessStyles(obj);
+
 			obj.transform.SetParent(MissionSectionTransform, false);

 			progressPanel = obj.GetComponent<CW_ProgressPanel>();
@@ -182,6 +212,9 @@

 		private void CreateMissionSections(IList<IMissionSection> sections)
 		{
+			if (windowInterface == null)
+				return;
+
 			if (sections == null)
 				return;

@@ -211,6 +244,8 @@

 			obj.transform.SetParent(MissionSectionTransform, false);

+			windowInterface.ProcessStyles(obj);
+
 			CW_MissionSection missionObject = obj.GetComponent<CW_MissionSection>();

 			if (missionObject == null)
@@ -278,7 +313,7 @@
 			currentMission.SetMissionVisible(true);

 			if (MissionTitle != null)
-				MissionTitle.text = currentMission.MissionTitle + ":";
+				MissionTitle.OnTextUpdate.Invoke(currentMission.MissionTitle + ":");

 			if (MissionEdit != null)
 			{
@@ -317,7 +352,7 @@
 					progressPanel.SetProgressVisible(true);

 				if (MissionTitle != null)
-					MissionTitle.text = "Progress Nodes:";
+					MissionTitle.OnTextUpdate.Invoke("Progress Nodes:");

 				if (MainPanelTooltip != null)
 					MainPanelTooltip.SetNewText("Go To Contracts");
@@ -331,7 +366,7 @@
 					currentMission.SetMissionVisible(true);

 				if (MissionTitle != null && currentMission != null)
-					MissionTitle.text = currentMission.MissionTitle + ":";
+					MissionTitle.OnTextUpdate.Invoke(currentMission.MissionTitle + ":");

 				if (MainPanelTooltip != null)
 					MainPanelTooltip.SetNewText("Go To Progress Records");
@@ -345,6 +380,9 @@
 			if (popupOpen)
 				return;

+			if (windowInterface == null)
+				return;
+
 			if (SortPrefab == null)
 				return;

@@ -353,6 +391,8 @@

 			GameObject obj = Instantiate(SortPrefab);

+			windowInterface.ProcessStyles(obj);
+
 			obj.transform.SetParent(transform, false);

 			CW_SortMenu sortObject = obj.GetComponent<CW_SortMenu>();
@@ -361,6 +401,8 @@
 				return;

 			sortObject.setSort(currentMission.MissionInterface);
+
+			UpdateFontSize(sortObject.gameObject, windowInterface.LargeFont ? 1 : 0);

 			popupOpen = true;
 		}
@@ -413,6 +455,8 @@

 			obj.transform.SetParent(transform, false);

+			windowInterface.ProcessStyles(obj);
+
 			CW_MissionSelect selectorObject = obj.GetComponent<CW_MissionSelect>();

 			if (selectorObject == null)
@@ -420,54 +464,59 @@

 			selectorObject.setMission(windowInterface.GetMissions);

+			UpdateFontSize(selectorObject.gameObject, windowInterface.LargeFont ? 1 : 0);
+
 			popupOpen = true;
 		}

 		public void showCreator(IContractSection contract)
 		{
+			if (MissionCreatePrefab == null)
+				return;
+
+			if (windowInterface == null)
+				return;
+
+			if (contract == null)
+				return;
+
+			GameObject obj = Instantiate(MissionCreatePrefab);
+
+			windowInterface.ProcessStyles(obj);
+
+			obj.transform.SetParent(transform, false);
+
+			CW_MissionCreate creatorObject = obj.GetComponent<CW_MissionCreate>();
+
+			if (creatorObject == null)
+				return;
+
+			creatorObject.setPanel(contract);
+
+			UpdateFontSize(creatorObject.gameObject, windowInterface.LargeFont ? 1 : 0);
+
+			popupOpen = true;
+		}
+
+		public void showEditor()
+		{
 			if (popupOpen)
 				return;

-			if (MissionCreatePrefab == null)
-				return;
-
-			if (windowInterface == null)
-				return;
-
-			if (contract == null)
-				return;
-
-			GameObject obj = Instantiate(MissionCreatePrefab);
+			if (MissionEditPrefab == null)
+				return;
+
+			if (windowInterface == null)
+				return;
+
+			if (currentMission == null)
+				return;
+
+			GameObject obj = Instantiate(MissionEditPrefab);

 			obj.transform.SetParent(transform, false);

-			CW_MissionCreate creatorObject = obj.GetComponent<CW_MissionCreate>();
-
-			if (creatorObject == null)
-				return;
-
-			creatorObject.setPanel(contract);
-
-			popupOpen = true;
-		}
-
-		public void showEditor()
-		{
-			if (popupOpen)
-				return;
-
-			if (MissionEditPrefab == null)
-				return;
-
-			if (windowInterface == null)
-				return;
-
-			if (currentMission == null)
-				return;
-
-			GameObject obj = Instantiate(MissionEditPrefab);
-
-			obj.transform.SetParent(transform, false);
+			windowInterface.ProcessStyles(obj);

 			CW_MissionEdit editorObject = obj.GetComponent<CW_MissionEdit>();

@@ -475,6 +524,8 @@
 				return;

 			editorObject.setMission(currentMission.MissionInterface);
+
+			UpdateFontSize(editorObject.gameObject, windowInterface.LargeFont ? 1 : 0);

 			popupOpen = true;
 		}
@@ -510,8 +561,12 @@

 			GameObject obj = Instantiate(RebuildPrefab);

+			windowInterface.ProcessStyles(obj);
+
 			obj.transform.SetParent(transform, false);

+			UpdateFontSize(obj, windowInterface.LargeFont ? 1 : 0);
+
 			popupOpen = true;
 		}

@@ -528,6 +583,8 @@

 			GameObject obj = Instantiate(ScalarPrefab);

+			windowInterface.ProcessStyles(obj);
+
 			obj.transform.SetParent(transform, false);

 			CW_Scale scalarObject = obj.GetComponent<CW_Scale>();
@@ -537,6 +594,8 @@

 			scalarObject.setScalar();

+			UpdateFontSize(scalarObject.gameObject, windowInterface.LargeFont ? 1 : 0);
+
 			popupOpen = true;
 		}

@@ -553,6 +612,8 @@

 			GameObject obj = Instantiate(ToolbarPrefab);

+			windowInterface.ProcessStyles(obj);
+
 			obj.transform.SetParent(transform, false);

 			CW_Toolbar toolbarObject = obj.GetComponent<CW_Toolbar>();
@@ -562,6 +623,8 @@

 			toolbarObject.setToolbar();

+			UpdateFontSize(toolbarObject.gameObject, windowInterface.LargeFont ? 1 : 0);
+
 			popupOpen = true;
 		}

@@ -578,6 +641,8 @@

 			GameObject obj = Instantiate(AgencyPrefab);

+			windowInterface.ProcessStyles(obj);
+
 			obj.transform.SetParent(transform, false);

 			CW_AgencyPanel agencyObject = obj.GetComponent<CW_AgencyPanel>();
@@ -587,6 +652,8 @@

 			agencyObject.setAgent(contract.AgencyName, contract.AgencyLogo);

+			UpdateFontSize(agencyObject.gameObject, windowInterface.LargeFont ? 1 : 0);
+
 			popupOpen = true;
 		}

@@ -603,6 +670,8 @@

 			GameObject obj = Instantiate(MissionAddPrefab);

+			windowInterface.ProcessStyles(obj);
+
 			obj.transform.SetParent(transform, false);

 			CW_MissionAdd adderObject = obj.GetComponent<CW_MissionAdd>();
@@ -611,6 +680,8 @@
 				return;

 			adderObject.setMission(windowInterface.GetMissions, contract);
+
+			UpdateFontSize(adderObject.gameObject, windowInterface.LargeFont ? 1 : 0);

 			popupOpen = true;
 		}
@@ -784,16 +855,16 @@

 		public void UpdateFontSize(GameObject obj, int s)
 		{
-			var texts = obj.GetComponentsInChildren<Text>();
+			var texts = obj.GetComponentsInChildren<TextHandler>(true);

 			for (int i = texts.Length - 1; i >= 0; i--)
 			{
-				Text t = texts[i];
+				TextHandler t = texts[i];

 				if (t == null)
 					continue;

-				t.fontSize += s;
+				t.OnFontChange.Invoke(s);
 			}
 		}


Ensure that organization contains a suspended notes value when the suspension type is other.

--- Source/Core/Validation/OrganizationValidator.cs
+++ Source/Core/Validation/OrganizationValidator.cs
@@ -21,7 +21,8 @@
             RuleFor(o => o.SuspensionDate).NotEmpty().When(o => o.IsSuspended).WithMessage("Please specify a valid suspension date.");
             RuleFor(o => o.SuspensionDate).Equal((DateTime?)null).Unless(o => o.IsSuspended).WithMessage("The suspension date cannot be set while an organization is not suspended.");
             RuleFor(o => o.SuspendedByUserId).NotEmpty().When(o => o.IsSuspended).WithMessage("Please specify a user id of user that suspended this organization.");
-            RuleFor(o => o.SuspendedByUserId).Equal((string)null).Unless(o => o.IsSuspended).WithMessage("The suspended by user id cannot be set while an organization is not suspended.");
+            RuleFor(o => o.SuspendedByUserId).Equal((string)null).Unless(o => o.IsSuspended).WithMessage("The suspended by user id cannot be set while an organization is not suspended."); ;
+            RuleFor(o => o.SuspensionNotes).NotEmpty().When(o => o.IsSuspended && o.SuspensionCode.HasValue && o.SuspensionCode == SuspensionCode.Other).WithMessage("Please specify a suspension note.");
         }
     }
 }


added tests for #935 to make sure Shapefiles are saved with correct M and Z values

--- Source/DotSpatial.Data.Tests/FeatureSetTests.cs
+++ Source/DotSpatial.Data.Tests/FeatureSetTests.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Data;
 using System.IO;
 using DotSpatial.NTSExtension;
@@ -205,7 +206,7 @@
             Assert.DoesNotThrow(() => fs1.Intersection(fs2, FieldJoinType.All, null));
         }

-        [Test(Description =@"Check whether the correct number of features is copied including the attributes.")]
+        [Test(Description = @"Check whether the correct number of features is copied including the attributes.")]
         public void CopySubsetWithAttributes()
         {
             IFeatureSet fs = BuildFeatureSet();
@@ -265,5 +266,138 @@
             Assert.AreEqual(res6.Features.Count, 3);
             Assert.AreEqual(res6.Features[0].DataRow.ItemArray.Length, 0);
         }
+
+        [Test(Description = @"Check whether point features are saved with correct M/Z extent and value.")]
+        [TestCase(CoordinateType.Regular)]
+        [TestCase(CoordinateType.M)]
+        [TestCase(CoordinateType.Z)]
+        public void SavePointToShapefileWithMandZ(CoordinateType c)
+        {
+            var fileName = FileTools.GetTempFileName(".shp");
+
+            try
+            {
+                var fs = new FeatureSet(FeatureType.Point)
+                {
+                    Projection = KnownCoordinateSystems.Geographic.World.WGS1984,
+                    CoordinateType = c
+                };
+
+                fs.AddFeature(new Point(new Coordinate(1, 2, 7, 4)));
+
+                Assert.DoesNotThrow(() => fs.SaveAs(fileName, true));
+
+                var loaded = FeatureSet.Open(fileName);
+
+                if (c == CoordinateType.Regular) //regular coordinates don't have m values
+                {
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.Coordinates[0].M);
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.EnvelopeInternal.Minimum.M);
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.EnvelopeInternal.Maximum.M);
+                }
+                else // m or z coordinates have m values
+                {
+                    Assert.AreEqual(4, loaded.Features[0].Geometry.Coordinates[0].M);
+                    Assert.AreEqual(4, loaded.Features[0].Geometry.EnvelopeInternal.Minimum.M);
+                    Assert.AreEqual(4, loaded.Features[0].Geometry.EnvelopeInternal.Maximum.M);
+                }
+
+                if (c == CoordinateType.Z) // z coordinates have z values
+                {
+                    Assert.AreEqual(7, loaded.Features[0].Geometry.Coordinates[0].Z);
+                    Assert.AreEqual(7, loaded.Features[0].Geometry.EnvelopeInternal.Minimum.Z);
+                    Assert.AreEqual(7, loaded.Features[0].Geometry.EnvelopeInternal.Maximum.Z);
+                }
+                else // regular and m coordinates don't have z values
+                {
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.Coordinates[0].Z);
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.EnvelopeInternal.Minimum.Z);
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.EnvelopeInternal.Maximum.Z);
+                }
+            }
+            finally
+            {
+                FileTools.DeleteShapeFile(fileName);
+            }
+        }
+
+        [Test(Description = @"Check whether polygon/line/multipoint features are saved with correct M/Z extent and value.")]
+        [TestCase(CoordinateType.Regular, FeatureType.Line)]
+        [TestCase(CoordinateType.M, FeatureType.Line)]
+        [TestCase(CoordinateType.Z, FeatureType.Line)]
+        [TestCase(CoordinateType.Regular, FeatureType.Polygon)]
+        [TestCase(CoordinateType.M, FeatureType.Polygon)]
+        [TestCase(CoordinateType.Z, FeatureType.Polygon)]
+        [TestCase(CoordinateType.Regular, FeatureType.MultiPoint)]
+        [TestCase(CoordinateType.M, FeatureType.MultiPoint)]
+        [TestCase(CoordinateType.Z, FeatureType.MultiPoint)]
+        public void SaveFeatureToShapefileWithMandZ(CoordinateType c, FeatureType ft)
+        {
+            var fileName = FileTools.GetTempFileName(".shp");
+
+            try
+            {
+                List<Coordinate> coords = new List<Coordinate> {
+                    new Coordinate(1, 2, 7, 4),
+                    new Coordinate(3, 4, 5, 6),
+                    new Coordinate(5, 6, 3, 8),
+                    new Coordinate(7, 8, 9, 10),
+                    new Coordinate(1, 2, 7, 4)};
+
+                var fs = new FeatureSet(ft)
+                {
+                    Projection = KnownCoordinateSystems.Geographic.World.WGS1984,
+                    CoordinateType = c
+                };
+
+                switch (ft)
+                {
+                    case FeatureType.Line:
+                        fs.AddFeature(new LineString(coords.ToArray()));
+                        break;
+                    case FeatureType.Polygon:
+                        fs.AddFeature(new Polygon(new LinearRing(coords.ToArray())));
+                        break;
+                    case FeatureType.MultiPoint:
+                        coords.RemoveAt(4);
+                        fs.AddFeature(new MultiPoint(coords.CastToPointArray()));
+                        break;
+                }
+
+                Assert.DoesNotThrow(() => fs.SaveAs(fileName, true));
+
+                var loaded = FeatureSet.Open(fileName);
+
+                if (c == CoordinateType.Regular) //regular coordinates don't have m values
+                {
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.Coordinates[0].M);
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.EnvelopeInternal.Minimum.M);
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.EnvelopeInternal.Maximum.M);
+                }
+                else // m or z coordinates have m values
+                {
+                    Assert.AreEqual(4, loaded.Features[0].Geometry.Coordinates[0].M);
+                    Assert.AreEqual(4, loaded.Features[0].Geometry.EnvelopeInternal.Minimum.M);
+                    Assert.AreEqual(10, loaded.Features[0].Geometry.EnvelopeInternal.Maximum.M);
+                }
+
+                if (c == CoordinateType.Z) // z coordinates have z values
+                {
+                    Assert.AreEqual(7, loaded.Features[0].Geometry.Coordinates[0].Z);
+                    Assert.AreEqual(3, loaded.Features[0].Geometry.EnvelopeInternal.Minimum.Z);
+                    Assert.AreEqual(9, loaded.Features[0].Geometry.EnvelopeInternal.Maximum.Z);
+                }
+                else // regular and m coordinates don't have z values
+                {
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.Coordinates[0].Z);
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.EnvelopeInternal.Minimum.Z);
+                    Assert.AreEqual(double.NaN, loaded.Features[0].Geometry.EnvelopeInternal.Maximum.Z);
+                }
+            }
+            finally
+            {
+                FileTools.DeleteShapeFile(fileName);
+            }
+        }
     }
 }


Added an example to wrong label placement issue (interactive)

--- Source/Examples/ExampleLibrary/Issues/Issues.cs
+++ Source/Examples/ExampleLibrary/Issues/Issues.cs
@@ -10,6 +10,7 @@
 namespace ExampleLibrary
 {
     using System;
+    using System.Threading;
     using System.Collections.Generic;

     using OxyPlot;
@@ -748,6 +749,59 @@
             return plotModel1;
         }

+        [Example("Wrong label placement for category axis when Angle = 45")]
+        public static PlotModel LabelPlacementCategoryAxisWhenAxisAngleIs45()
+        {
+            var plotModel1 = new PlotModel { Title = "Wrong label placement for category axis when Angle = 45", Subtitle = "The labels should not be clipped. Click on text annotation to change tha angle." };
+
+            Action<AxisPosition> createAxis = (AxisPosition position) =>
+            {
+                var categoryAxis = new CategoryAxis() { Position = position, Angle = 45 };
+
+                categoryAxis.Labels.Add("Very looooong and big label");
+                categoryAxis.Labels.Add("Very looooong and big label");
+                categoryAxis.Labels.Add("Very looooong and big label");
+                categoryAxis.Labels.Add("Very looooong and big label");
+                plotModel1.Axes.Add(categoryAxis);
+            };
+
+            createAxis(AxisPosition.Bottom);
+            createAxis(AxisPosition.Left);
+            createAxis(AxisPosition.Right);
+            createAxis(AxisPosition.Top);
+
+            var textAnnotation = new TextAnnotation() { Text = "Hold mouse to increase angle", TextPosition = new DataPoint(0, 5), TextHorizontalAlignment = HorizontalAlignment.Left, TextVerticalAlignment = VerticalAlignment.Top };
+            plotModel1.Annotations.Add(textAnnotation);
+            bool? stopTask = null;
+
+
+            Timer t = new Timer(o =>
+            {
+                // Angles are the same for all axes.
+                double angle = 0;
+
+                foreach (var axis in plotModel1.Axes)
+                {
+                    angle = (axis.Angle + 181) % 360 - 180;
+                    axis.Angle = angle;
+                }
+
+                plotModel1.Subtitle = string.Format("Current angle is {0}", angle);
+                plotModel1.InvalidatePlot(false);
+            }, null, -1, 50);
+
+            textAnnotation.MouseDown += (o, e) => { t.Change(0, 50); };
+            plotModel1.MouseUp += (o, e) => { t.Change(-1, 50); };
+
+            var columnSeries = new ColumnSeries();
+            columnSeries.Items.Add(new ColumnItem(5));
+            columnSeries.Items.Add(new ColumnItem(3));
+            columnSeries.Items.Add(new ColumnItem(7));
+            columnSeries.Items.Add(new ColumnItem(2));
+            plotModel1.Series.Add(columnSeries);
+            return plotModel1;
+        }
+
         [Example("#180: Two vertical axes on the same position")]
         public static PlotModel TwoVerticalAxisOnTheSamePosition()
         {


[FolderInfo] Add culture to folder info in order to create page in certain site variation only

--- Source/GSoft.Dynamite/Definitions/FolderInfo.cs
+++ Source/GSoft.Dynamite/Definitions/FolderInfo.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -76,5 +77,10 @@
         /// The Welcome Page of the folder
         /// </summary>
         public PageInfo WelcomePage { get; set; }
+
+        /// <summary>
+        /// The culture to create that folder hierarchie. If null, create in all culture.
+        /// </summary>
+        public CultureInfo Locale { get; set; }
     }
 }


GSF.Communication: Updated TlsClient on Mono builds to default to Tls1.2 since newer builds of Mono support this.

--- Source/Libraries/GSF.Communication/TlsClient.cs
+++ Source/Libraries/GSF.Communication/TlsClient.cs
@@ -227,12 +227,7 @@
             m_defaultCertificateChecker = new SimpleCertificateChecker();
             LocalCertificateSelectionCallback = DefaultLocalCertificateSelectionCallback;
             m_clientCertificates = new X509Certificate2Collection();
-        #if MONO
-            // Tls12 is not supported under Mono as of v3.8.0
-            m_enabledSslProtocols = SslProtocols.Tls;
-        #else
             m_enabledSslProtocols = SslProtocols.Tls12;
-        #endif
             CheckCertificateRevocation = true;

             TrustedCertificatesPath = DefaultTrustedCertificatesPath;


Unexpectedly high translated character count

When using Google Translate

--- Source/Main/UI/Translation/AutoTranslateForm.cs
+++ Source/Main/UI/Translation/AutoTranslateForm.cs
@@ -797,6 +797,7 @@
 			{
 				foreach (DataRow row in table.Rows)
 				{
+					items.Clear();
 					if (row != null)
 					{
 						if (bw.CancellationPending)


Disable Add to Plate until View3DWidget target available

- Issue MatterHackers/MCCentral#3961
Add to Plate enabled when no printer/part available

--- Library/Widgets/PrintLibraryWidget.cs
+++ Library/Widgets/PrintLibraryWidget.cs
@@ -589,8 +589,9 @@
 				},
 				IsEnabled = (selectedListItems, listView) =>
 				{
-					// Multiselect - disallow containers
-					return listView.SelectedItems.Any()
+					// Multiselect - disallow containers, require View3DWidget context
+					return ApplicationController.Instance.DragDropData.View3DWidget != null
+						&& listView.SelectedItems.Any()
 						&& listView.SelectedItems.All(i => !(i.Model is ILibraryContainer));
 				}
 			});


Just some comments

Just some comments

--- LightDatamodel/GenericDataProvider.cs
+++ LightDatamodel/GenericDataProvider.cs
@@ -29,9 +29,15 @@

 		#region IDataProvider Members

+		/// <summary>
+		/// This will return the corresponding DBNull value. Eg. a date dbnull could be the classic date 1-1-1
+		/// DBNull will be eliminated from the code. There's no such thing as a secondary meaning/use of a field.
+		/// If you need the implicit information on whether the field has been sat or not, add a boolean to the model!
+		/// </summary>
+		/// <param name="type"></param>
+		/// <returns></returns>
 		public virtual object GetNullValue(Type type)
 		{
-			//in case of DBNULL
 			if(type == typeof(int))
 				return int.MinValue;
 			else if(type == typeof(short))
@@ -52,7 +58,9 @@
 			return null;
 		}

-
+		/// <summary>
+		/// Will get or set the connection string. All DBs I've meet is able to connect throug the use a single connection string. Even Oracle! (It can be rather huge though)
+		/// </summary>
 		public virtual string ConnectionString
 		{
 			get{return m_connection.ConnectionString;}
@@ -67,6 +75,12 @@
 			return "?";
 		}

+		/// <summary>
+		/// Will delete a specified row from the DB. Will throw an exception if non or more than 1 are updated
+		/// </summary>
+		/// <param name="tablename"></param>
+		/// <param name="primarycolumnname"></param>
+		/// <param name="primaryvalue"></param>
 		public virtual void DeleteRow(string tablename, string primarycolumnname, object primaryvalue)
 		{
 			if(m_connection.State != ConnectionState.Open) m_connection.Open();
@@ -85,7 +99,14 @@
 			}
 		}

-		public virtual  Data[] SelectRow(string tablename, string primarycolumnname, object primaryvalue)
+		/// <summary>
+		/// Will return a single row from the DB
+		/// </summary>
+		/// <param name="tablename"></param>
+		/// <param name="primarycolumnname"></param>
+		/// <param name="primaryvalue"></param>
+		/// <returns></returns>
+		public virtual Data[] SelectRow(string tablename, string primarycolumnname, object primaryvalue)
 		{
 			if(m_connection.State != ConnectionState.Open) m_connection.Open();
 			IDbCommand cmd = m_connection.CreateCommand();
@@ -107,6 +128,12 @@
 			}
 		}

+		/// <summary>
+		/// Will select multiple rows from the DB through the use of QueryModel
+		/// </summary>
+		/// <param name="tablename"></param>
+		/// <param name="operation"></param>
+		/// <returns></returns>
 		public virtual Data[][] SelectRows(string tablename, QueryModel.Operation operation)
 		{
 			ArrayList values = new ArrayList();
@@ -183,6 +210,13 @@
 			}
 		}

+		/// <summary>
+		/// Will select multiple rows from the DB
+		/// </summary>
+		/// <param name="tablename"></param>
+		/// <param name="filter"></param>
+		/// <param name="values">Used if the filter is parametized. Eg. ... MyCol = ? AND YourCol = ? ...</param>
+		/// <returns></returns>
 		public virtual Data[][] SelectRows(string tablename, string filter, object[] values)
 		{
 			if(m_connection.State != ConnectionState.Open) m_connection.Open();
@@ -220,11 +254,24 @@
 			}
 		}

+		/// <summary>
+		/// Selects multiple rows from DB.
+		/// </summary>
+		/// <param name="tablename"></param>
+		/// <param name="filter">Non parametized. Eg. MyCol = "Cheese" AND ...</param>
+		/// <returns></returns>
 		public virtual Data[][] SelectRows(string tablename, string filter)
 		{
 			return SelectRows(tablename, filter, null);
 		}

+		/// <summary>
+		/// Will update a given row in the DB. Will throw an exception if non or more than 1 are updated
+		/// </summary>
+		/// <param name="tablename"></param>
+		/// <param name="primarycolumnname"></param>
+		/// <param name="primaryvalue"></param>
+		/// <param name="values"></param>
 		public virtual void UpdateRow(string tablename, string primarycolumnname, object primaryvalue, params Data[] values)
 		{
 			if(m_connection.State != ConnectionState.Open) m_connection.Open();
@@ -248,6 +295,11 @@
 			}
 		}

+		/// <summary>
+		/// Will insert a new row in the DB
+		/// </summary>
+		/// <param name="tablename"></param>
+		/// <param name="values"></param>
 		public virtual void InsertRow(string tablename, params Data[] values)
 		{
 			if(m_connection.State != ConnectionState.Open) m_connection.Open();
@@ -293,7 +345,7 @@

 		public virtual Data[] GetTableStructure(string tablename)
 		{
-			return GetStructure("SELECT * FROM [" + tablename + "] WHERE 1 = 0");
+			return GetStructure("SELECT * FROM " + QuoteTablename(tablename) + " WHERE 1 = 0");
 		}

 		public virtual void Close()


use inmemory mq and ef

use inmemory mq and ef

--- Src/Sample/Sample.CommandServiceCore/Startup.cs
+++ Src/Sample/Sample.CommandServiceCore/Startup.cs
@@ -80,19 +80,19 @@
                     .AddJsonNet()
                     .AddEntityFrameworkComponents(typeof(RepositoryBase<>))
                     .AddRelationalMessageStore<SampleModelContext>()
-                    .AddConfluentKafka()
-                    //.AddInMemoryMessageQueue()
+                    //.AddConfluentKafka()
+                    .AddInMemoryMessageQueue()
                     //.AddRabbitMQ(rabbitConnectionFactory)
                     .AddMessagePublisher("eventTopic")
                     .AddCommandBus(Environment.MachineName, serialCommandManager: new SerialCommandManager())
                     .AddDbContextPool<SampleModelContext>(options =>
                     {
                         //options.EnableSensitiveDataLogging();
-                        options.UseLazyLoadingProxies();
-                        options.UseSqlServer(Configuration.Instance.GetConnectionString(nameof(SampleModelContext)));
+                        //options.UseLazyLoadingProxies();
+                        //options.UseSqlServer(Configuration.Instance.GetConnectionString(nameof(SampleModelContext)));
                         //options.UseMySQL(Configuration.Instance.GetConnectionString($"{nameof(SampleModelContext)}.MySql"));
                         //options.UseMongoDb(Configuration.Instance.GetConnectionString($"{nameof(SampleModelContext)}.MongoDb"));
-                        //options.UseInMemoryDatabase(nameof(SampleModelContext));
+                        options.UseInMemoryDatabase(nameof(SampleModelContext));
                     })
                     ;
             //services.AddLog4Net(new Log4NetProviderOptions {EnableScope = false});


Fixed numerical issue with step size

Fixed numerical issue with step size

--- LiveSPICE/TransientSimulation.xaml.cs
+++ LiveSPICE/TransientSimulation.xaml.cs
@@ -146,7 +146,7 @@
             {
                 try
                 {
-                    Circuit.Quantity h = new Circuit.Quantity(1 / (sampleRate * Oversample), Circuit.Units.s);
+                    Circuit.Quantity h = new Circuit.Quantity(Constant.One / (sampleRate * Oversample), Circuit.Units.s);
                     if (solution == null || solution.TimeStep != h)
                     {
                         solution = Circuit.TransientSolution.SolveCircuit(circuit, h, Log);


Removed SharepointConnection skip. Uuthenticated connection has not to be authenticated again anymore. Hidden parameters are not settable in the portal and not retrievable. So there is no reason to add them to the armtemlate. Therefor now skipped.

--- LogicAppTemplate/TemplateGenerator.cs
+++ LogicAppTemplate/TemplateGenerator.cs
@@ -799,12 +799,19 @@

                         }
-                        else if (concatedId.EndsWith("/managedApis/sharepointonline')]"))
-                        {
+                        //else if (concatedId.EndsWith("/managedApis/sharepointonline')]"))
+                        //{
                             //skip because otherwise authenticated connection has to be authenticated again.
-                        }
+                        //}
                         else
                         {
+                            //check for hidden constraint
+                            if ((parameter.Value["uiDefinition"]["constraints"]["hidden"]?.Value<bool>() ?? false))
+                            {
+                                continue;
+                            }
+
+
                             //todo check this!
                             object parameterValue = null;
                             if(connectionInstance["properties"]["nonSecretParameterValues"] != null)
@@ -844,7 +851,7 @@
                 }
             }

-            if (useGateway)
+            if (useGateway) //&& !concatedId.EndsWith("/managedApis/sharepointonline')]")
             {
                 string currentvalue = "";
                 if ( connectionInstance["properties"]["nonSecretParameterValues"] != null )