Small fix

Small fix

--- source/FFImageLoading.Cross/MvxCachedImageView.cs
+++ source/FFImageLoading.Cross/MvxCachedImageView.cs
@@ -406,9 +406,11 @@
                     _lastImageSource = ffSource;
                 });

-                imageLoader.Error(OnError);
-
-                imageLoader.DownloadStarted(OnDownloadStarted);
+                if (OnError != null)
+                    imageLoader.Error(OnError);
+
+                if (OnDownloadStarted != null)
+                    imageLoader.DownloadStarted(OnDownloadStarted);

                 imageLoader.DownloadProgress((progress) =>
                                              OnDownloadProgress?.Invoke(progress));


Add literal string support

Add literal string support

--- source/XSharp/XSharp/Assembler/Gen1/DataMember.cs
+++ source/XSharp/XSharp/Assembler/Gen1/DataMember.cs
@@ -20,6 +20,7 @@
         public string RawAsm = null;
         private string Size;
         private string StringValue;
+        private string Type;

         // Hack for not to emit raw data. See RawAsm
         public DataMember()
@@ -34,7 +35,14 @@
             var xBytes2 = new byte[xBytes.Length + 1];
             xBytes.CopyTo(xBytes2, 0);
             xBytes2[xBytes2.Length - 1] = 0;
-            RawDefaultValue = xBytes2;
+            RawDefaultValue = xBytes2; StringValue = aValue;
+        }
+
+        public DataMember(string aName, string aValue, string aType, bool literal)
+        {
+            Name = aName;
+            Type = aType;
+            StringValue = aValue;
         }

         public DataMember(string aName, string size, string aValue)
@@ -258,11 +266,22 @@

             if (StringValue != null)
             {
-                aOutput.Write(Name);
-                aOutput.Write(" ");
-                aOutput.Write(Size);
-                aOutput.Write(" ");
-                aOutput.Write(StringValue);
+                if (Type != null)
+                {
+                    aOutput.Write(Name);
+                    aOutput.Write(" ");
+                    aOutput.Write(Type);
+                    aOutput.Write(" ");
+                    aOutput.Write(StringValue);
+                }
+                else
+                {
+                    aOutput.Write(Name);
+                    aOutput.Write(" ");
+                    aOutput.Write(Size);
+                    aOutput.Write(" ");
+                    aOutput.Write(StringValue);
+                }
                 return;
             }


Fixte nog gauw een security issue...

Fixte nog gauw een security issue...

--- Solution/Chiro.Gap.Services/UitstappenService.svc.cs
+++ Solution/Chiro.Gap.Services/UitstappenService.svc.cs
@@ -1,14 +1,14 @@
 /*
- * Copyright 2008-2015 the GAP developers. See the NOTICE file at the
+ * Copyright 2008-2015 the GAP developers. See the NOTICE file at the
  * top-level directory of this distribution, and at
  * https://gapwiki.chiro.be/copyright
- *
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- *
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -209,6 +209,8 @@
         public DeelnemerDetail DeelnemerOphalen(int deelnemerId)
         {
             var resultaat = _deelnemersRepo.Select().FirstOrDefault(dln => dln.ID == deelnemerId);
+            Gav.Check(resultaat.GelieerdePersoon);
+			      Gav.Check(resultaat.Uitstap);
             return Mapper.Map<Deelnemer, DeelnemerDetail>(resultaat);
         }

@@ -226,14 +228,14 @@
         }

         /// <summary>
-        /// Haalt informatie over de bivakaangifte op van de groep <paramref name="groepId"/> voor diens recentste
+        /// Haalt informatie over de bivakaangifte op van de groep <paramref name="groepId"/> voor diens recentste
         /// werkJaar.
         /// </summary>
         /// <param name="groepId">
         /// De groep waarvan info wordt gevraagd
         /// </param>
         /// <returns>
-        /// Een lijstje met de geregistreerde bivakken en feedback over wat er op dit moment moet gebeuren
+        /// Een lijstje met de geregistreerde bivakken en feedback over wat er op dit moment moet gebeuren
         /// voor de bivakaangifte
         /// </returns>
         public BivakAangifteLijstInfo BivakStatusOphalen(int groepId)
@@ -365,7 +367,7 @@
             var uitstap = _uitstappenRepo.ByID(uitstapId);
             Gav.Check(uitstap);
             var groep = uitstap.GroepsWerkJaar.Groep;
-
+
             // zoek of maak adres
             var adres = _adressenMgr.ZoekenOfMaken(adresInfo, _adressenRepo.Select(), _straatNamenRepo.Select(), _woonPlaatsenRepo.Select(), _landenRepo.Select());

@@ -490,7 +492,7 @@
         /// </summary>
         /// <param name="gelieerdePersoonIDs">ID's van in te schrijven gelieerde personen</param>
         /// <param name="geselecteerdeUitstapId">ID van uitstap waarvoor in te schrijven</param>
-        /// <param name="logistiekDeelnemer">Bepaalt of al dan niet ingeschreven wordt als
+        /// <param name="logistiekDeelnemer">Bepaalt of al dan niet ingeschreven wordt als
         /// logistieker</param>
         /// <returns>De basisgegevens van de uitstap, zodat die in de feedback gebruikt kan worden</returns>
         public UitstapInfo Inschrijven(IList<int> gelieerdePersoonIDs, int geselecteerdeUitstapId,


GSF.ServiceProcess: Fixed authorization logic in ServiceHelper for remote console commands with aliases.

--- Source/Libraries/GSF.ServiceProcess/ServiceHelper.cs
+++ Source/Libraries/GSF.ServiceProcess/ServiceHelper.cs
@@ -2638,7 +2638,6 @@
                     try
                     {
                         requestInfo = new ClientRequestInfo(client, request);
-                        string resource = requestInfo.Request.Command;

                         if (m_remoteCommandClientID == Guid.Empty)
                         {
@@ -2650,6 +2649,8 @@
                                 if (m_clientRequestHistory.Count > m_requestHistoryLimit)
                                     m_clientRequestHistory.RemoveRange(0, (m_clientRequestHistory.Count - m_requestHistoryLimit));
                             }
+
+                            ClientRequestHandler requestHandler = FindClientRequestHandler(request.Command);

                             // Check if remote client has permission to invoke the requested command.
                             if (m_secureRemoteInteractions)
@@ -2660,14 +2661,14 @@
                                     throw new SecurityException($"Authentication failure for client '{client.ClientUsername}'.");
                                 }

+                                string resource = requestHandler?.Command ?? requestInfo.Request.Command;
+
                                 if (SecurityProviderUtility.IsResourceSecurable(resource) && !SecurityProviderUtility.IsResourceAccessible(resource, client.ClientUser))
                                     throw new SecurityException($"Access to '{requestInfo.Request.Command}' is denied");
                             }

                             // Notify the consumer about the incoming request from client.
                             OnReceivedClientRequest(request, client);
-
-                            ClientRequestHandler requestHandler = FindClientRequestHandler(request.Command);

                             if ((object)requestHandler != null)
                             {


make task running better and use the correct cancellation token

--- src/Microsoft.ApiDesignGuidelines.Analyzers/Core/OperatorOverloadsHaveNamedAlternates.Fixer.cs
+++ src/Microsoft.ApiDesignGuidelines.Analyzers/Core/OperatorOverloadsHaveNamedAlternates.Fixer.cs
@@ -28,33 +28,31 @@
             return WellKnownFixAllProviders.BatchFixer;
         }

-        public sealed override Task RegisterCodeFixesAsync(CodeFixContext context)
+        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
         {
-            return Task.Run(() => context.RegisterCodeFix(new MyCodeAction(ct => Fix(context, ct)), context.Diagnostics.First()));
+            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
+            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
+            var generator = context.Document.Project?.LanguageServices?.GetService<SyntaxGenerator>();
+            if (semanticModel != null && generator != null)
+            {
+                context.RegisterCodeFix(new MyCodeAction(ct => Fix(context, root, generator, semanticModel, ct)), context.Diagnostics.First());
+            }
         }

-        private static async Task<Document> Fix(CodeFixContext context, CancellationToken cancellationToken)
+        private static async Task<Document> Fix(CodeFixContext context, SyntaxNode root, SyntaxGenerator generator, SemanticModel semanticModel, CancellationToken cancellationToken)
         {
-            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
-            var root = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
             var node = root.FindNode(context.Span);
-            var generator = context.Document.Project?.LanguageServices?.GetService<SyntaxGenerator>();
-            if (generator == null)
-            {
-                return context.Document;
-            }
-
             var diagnostic = context.Diagnostics.First();
             switch (diagnostic.Properties[OperatorOverloadsHaveNamedAlternatesAnalyzer.DiagnosticKindText])
             {
                 case OperatorOverloadsHaveNamedAlternatesAnalyzer.AddAlternateText:
                     var methodDeclaration = generator.GetDeclaration(node, DeclarationKind.Operator) ?? generator.GetDeclaration(node, DeclarationKind.ConversionOperator);
-                    var operatorOverloadSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken);
-                    var typeSymbol = (ITypeSymbol)operatorOverloadSymbol.ContainingSymbol;
+                    var operatorOverloadSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken);
+                    var typeSymbol = operatorOverloadSymbol.ContainingType;

                     // For C# the following `typeDeclarationSyntax` and `typeDeclaration` nodes are identical, but for VB they're different so in
                     // an effort to keep this as language-agnostic as possible, the heavy-handed approach is used.
-                    var typeDeclarationSyntax = typeSymbol.DeclaringSyntaxReferences.First().GetSyntax(context.CancellationToken);
+                    var typeDeclarationSyntax = typeSymbol.DeclaringSyntaxReferences.First().GetSyntax(cancellationToken);
                     var typeDeclaration = generator.GetDeclaration(typeDeclarationSyntax, DeclarationKind.Class);

                     SyntaxNode addedMember;
@@ -87,12 +85,12 @@
                     return context.Document.WithSyntaxRoot(root.ReplaceNode(typeDeclaration, newTypeDeclaration));
                 case OperatorOverloadsHaveNamedAlternatesAnalyzer.FixVisibilityText:
                     var badVisibilityNode = generator.GetDeclaration(node, DeclarationKind.Method) ?? generator.GetDeclaration(node, DeclarationKind.Property);
-                    var badVisibilitySymbol = semanticModel.GetDeclaredSymbol(badVisibilityNode, context.CancellationToken);
+                    var badVisibilitySymbol = semanticModel.GetDeclaredSymbol(badVisibilityNode, cancellationToken);
                     var symbolEditor = SymbolEditor.Create(context.Document);
                     var newSymbol = await symbolEditor.EditOneDeclarationAsync(badVisibilitySymbol,
-                        (documentEditor, syntaxNode, ct) => Task.Run(() => documentEditor.SetAccessibility(badVisibilityNode, Accessibility.Public))).ConfigureAwait(false);
+                        (documentEditor, syntaxNode) => documentEditor.SetAccessibility(badVisibilityNode, Accessibility.Public));
                     var newDocument = symbolEditor.GetChangedDocuments().Single();
-                    var newRoot = await newDocument.GetSyntaxRootAsync(context.CancellationToken);
+                    var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken);
                     return context.Document.WithSyntaxRoot(newRoot);
                 default:
                     return context.Document;


- Renamed enum tests

- Renamed enum tests

--- Source/Mosa.Test.Collection.x86.xUnit/EnumFixture.cs
+++ Source/Mosa.Test.Collection.x86.xUnit/EnumFixture.cs
@@ -15,217 +15,217 @@
 	public class EnumU1Fixture : X86TestFixture
 	{
 		[Fact]
-		public void Conversion()
+		public void PositiveConversion()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveConversion"));
 		}

 		[Fact]
-		public void PlusOne1()
+		public void PositivePlusOne1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositivePlusOne1"));
 		}

 		[Fact]
-		public void PlusOne2()
+		public void PositivePlusOne2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositivePlusOne2"));
 		}

 		[Fact]
-		public void MinusOne1()
+		public void PositiveMinusOne1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveMinusOne1"));
 		}

 		[Fact]
-		public void MinusOne2()
+		public void PositiveMinusOne2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveMinusOne2"));
 		}

 		[Fact]
-		public void Shl()
+		public void PositiveShl()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveShl"));
 		}

 		[Fact]
-		public void Shr()
+		public void PositiveShr()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveShr"));
 		}

 		[Fact]
-		public void Mul2()
+		public void PositiveMul2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveMul2"));
 		}

 		[Fact]
-		public void Div2()
+		public void PositiveDiv2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveDiv2"));
 		}

 		[Fact]
-		public void AssignPlusOne()
+		public void PositiveAssignPlusOne()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveAssignPlusOne"));
 		}

 		[Fact]
-		public void AssignMinusOne()
+		public void PositiveAssignMinusOne()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveAssignMinusOne"));
 		}

 		[Fact]
-		public void Preincrement()
+		public void PositivePreincrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositivePreincrement"));
 		}

 		[Fact]
-		public void Predecrement()
+		public void PositivePredecrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositivePredecrement"));
 		}

 		[Fact]
-		public void Postincrement()
+		public void PositivePostincrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositivePostincrement"));
 		}

 		[Fact]
-		public void Postdecrement()
+		public void PositivePostdecrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositivePostdecrement"));
 		}

 		[Fact]
-		public void And()
+		public void PositiveAnd()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveAnd"));
 		}

 		[Fact]
-		public void Or()
+		public void PositiveOr()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveOr"));
 		}

 		[Fact]
-		public void XOr()
+		public void PositiveXOr()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveXOr"));
 		}

 		[Fact]
-		public void Equal1()
+		public void PositiveEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveEqual1"));
 		}

 		[Fact]
-		public void Equal2()
+		public void PositiveEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveEqual2"));
 		}

 		[Fact]
-		public void Equal3()
+		public void PositiveEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveEqual3"));
 		}

 		[Fact]
-		public void NotEqual1()
+		public void PositiveNotEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveNotEqual1"));
 		}

 		[Fact]
-		public void NotEqual2()
+		public void PositiveNotEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveNotEqual2"));
 		}

 		[Fact]
-		public void NotEqual3()
+		public void PositiveNotEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveNotEqual3"));
 		}

 		[Fact]
-		public void GreaterThan1()
+		public void PositiveGreaterThan1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveGreaterThan1"));
 		}

 		[Fact]
-		public void GreaterThan2()
+		public void PositiveGreaterThan2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveGreaterThan2"));
 		}

 		[Fact]
-		public void GreaterThan3()
+		public void PositiveGreaterThan3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveGreaterThan3"));
 		}

 		[Fact]
-		public void LessThan1()
+		public void PositiveLessThan1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveLessThan1"));
 		}

 		[Fact]
-		public void LessThan2()
+		public void PositiveLessThan2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveLessThan2"));
 		}

 		[Fact]
-		public void LessThan3()
+		public void PositiveLessThan3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveLessThan3"));
 		}

 		[Fact]
-		public void GreaterThanOrEqual1()
+		public void PositiveGreaterThanOrEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveGreaterThanOrEqual1"));
 		}

 		[Fact]
-		public void GreaterThanOrEqual2()
+		public void PositiveGreaterThanOrEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveGreaterThanOrEqual2"));
 		}

 		[Fact]
-		public void GreaterThanOrEqual3()
+		public void PositiveGreaterThanOrEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveGreaterThanOrEqual3"));
 		}

 		[Fact]
-		public void LessThanOrEqual1()
+		public void PositiveLessThanOrEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveLessThanOrEqual1"));
 		}

 		[Fact]
-		public void LessThanOrEqual2()
+		public void PositiveLessThanOrEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveLessThanOrEqual2"));
 		}

 		[Fact]
-		public void LessThanOrEqual3()
+		public void PositiveLessThanOrEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU1Class.PositiveLessThanOrEqual3"));
 		}
@@ -234,217 +234,217 @@
 	public class EnumU2Fixture : X86TestFixture
 	{
 		[Fact]
-		public void Conversion()
+		public void PositiveConversion()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveConversion"));
 		}

 		[Fact]
-		public void PlusOne1()
+		public void PositivePlusOne1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositivePlusOne1"));
 		}

 		[Fact]
-		public void PlusOne2()
+		public void PositivePlusOne2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositivePlusOne2"));
 		}

 		[Fact]
-		public void MinusOne1()
+		public void PositiveMinusOne1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveMinusOne1"));
 		}

 		[Fact]
-		public void MinusOne2()
+		public void PositiveMinusOne2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveMinusOne2"));
 		}

 		[Fact]
-		public void Shl()
+		public void PositiveShl()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveShl"));
 		}

 		[Fact]
-		public void Shr()
+		public void PositiveShr()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveShr"));
 		}

 		[Fact]
-		public void Mul2()
+		public void PositiveMul2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveMul2"));
 		}

 		[Fact]
-		public void Div2()
+		public void PositiveDiv2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveDiv2"));
 		}

 		[Fact]
-		public void AssignPlusOne()
+		public void PositiveAssignPlusOne()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveAssignPlusOne"));
 		}

 		[Fact]
-		public void AssignMinusOne()
+		public void PositiveAssignMinusOne()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveAssignMinusOne"));
 		}

 		[Fact]
-		public void Preincrement()
+		public void PositivePreincrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositivePreincrement"));
 		}

 		[Fact]
-		public void Predecrement()
+		public void PositivePredecrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositivePredecrement"));
 		}

 		[Fact]
-		public void Postincrement()
+		public void PositivePostincrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositivePostincrement"));
 		}

 		[Fact]
-		public void Postdecrement()
+		public void PositivePostdecrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositivePostdecrement"));
 		}

 		[Fact]
-		public void And()
+		public void PositiveAnd()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveAnd"));
 		}

 		[Fact]
-		public void Or()
+		public void PositiveOr()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveOr"));
 		}

 		[Fact]
-		public void XOr()
+		public void PositiveXOr()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveXOr"));
 		}

 		[Fact]
-		public void Equal1()
+		public void PositiveEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveEqual1"));
 		}

 		[Fact]
-		public void Equal2()
+		public void PositiveEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveEqual2"));
 		}

 		[Fact]
-		public void Equal3()
+		public void PositiveEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveEqual3"));
 		}

 		[Fact]
-		public void NotEqual1()
+		public void PositiveNotEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveNotEqual1"));
 		}

 		[Fact]
-		public void NotEqual2()
+		public void PositiveNotEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveNotEqual2"));
 		}

 		[Fact]
-		public void NotEqual3()
+		public void PositiveNotEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveNotEqual3"));
 		}

 		[Fact]
-		public void GreaterThan1()
+		public void PositiveGreaterThan1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveGreaterThan1"));
 		}

 		[Fact]
-		public void GreaterThan2()
+		public void PositiveGreaterThan2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveGreaterThan2"));
 		}

 		[Fact]
-		public void GreaterThan3()
+		public void PositiveGreaterThan3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveGreaterThan3"));
 		}

 		[Fact]
-		public void LessThan1()
+		public void PositiveLessThan1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveLessThan1"));
 		}

 		[Fact]
-		public void LessThan2()
+		public void PositiveLessThan2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveLessThan2"));
 		}

 		[Fact]
-		public void LessThan3()
+		public void PositiveLessThan3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveLessThan3"));
 		}

 		[Fact]
-		public void GreaterThanOrEqual1()
+		public void PositiveGreaterThanOrEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveGreaterThanOrEqual1"));
 		}

 		[Fact]
-		public void GreaterThanOrEqual2()
+		public void PositiveGreaterThanOrEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveGreaterThanOrEqual2"));
 		}

 		[Fact]
-		public void GreaterThanOrEqual3()
+		public void PositiveGreaterThanOrEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveGreaterThanOrEqual3"));
 		}

 		[Fact]
-		public void LessThanOrEqual1()
+		public void PositiveLessThanOrEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveLessThanOrEqual1"));
 		}

 		[Fact]
-		public void LessThanOrEqual2()
+		public void PositiveLessThanOrEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveLessThanOrEqual2"));
 		}

 		[Fact]
-		public void LessThanOrEqual3()
+		public void PositiveLessThanOrEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU2Class.PositiveLessThanOrEqual3"));
 		}
@@ -453,217 +453,217 @@
 	public class EnumU4Fixture : X86TestFixture
 	{
 		[Fact]
-		public void Conversion()
+		public void PositiveConversion()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveConversion"));
 		}

 		[Fact]
-		public void PlusOne1()
+		public void PositivePlusOne1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositivePlusOne1"));
 		}

 		[Fact]
-		public void PlusOne2()
+		public void PositivePlusOne2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositivePlusOne2"));
 		}

 		[Fact]
-		public void MinusOne1()
+		public void PositiveMinusOne1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveMinusOne1"));
 		}

 		[Fact]
-		public void MinusOne2()
+		public void PositiveMinusOne2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveMinusOne2"));
 		}

 		[Fact]
-		public void Shl()
+		public void PositiveShl()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveShl"));
 		}

 		[Fact]
-		public void Shr()
+		public void PositiveShr()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveShr"));
 		}

 		[Fact]
-		public void Mul2()
+		public void PositiveMul2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveMul2"));
 		}

 		[Fact]
-		public void Div2()
+		public void PositiveDiv2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveDiv2"));
 		}

 		[Fact]
-		public void AssignPlusOne()
+		public void PositiveAssignPlusOne()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveAssignPlusOne"));
 		}

 		[Fact]
-		public void AssignMinusOne()
+		public void PositiveAssignMinusOne()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveAssignMinusOne"));
 		}

 		[Fact]
-		public void Preincrement()
+		public void PositivePreincrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositivePreincrement"));
 		}

 		[Fact]
-		public void Predecrement()
+		public void PositivePredecrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositivePredecrement"));
 		}

 		[Fact]
-		public void Postincrement()
+		public void PositivePostincrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositivePostincrement"));
 		}

 		[Fact]
-		public void Postdecrement()
+		public void PositivePostdecrement()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositivePostdecrement"));
 		}

 		[Fact]
-		public void And()
+		public void PositiveAnd()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveAnd"));
 		}

 		[Fact]
-		public void Or()
+		public void PositiveOr()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveOr"));
 		}

 		[Fact]
-		public void XOr()
+		public void PositiveXOr()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveXOr"));
 		}

 		[Fact]
-		public void Equal1()
+		public void PositiveEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveEqual1"));
 		}

 		[Fact]
-		public void Equal2()
+		public void PositiveEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveEqual2"));
 		}

 		[Fact]
-		public void Equal3()
+		public void PositiveEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveEqual3"));
 		}

 		[Fact]
-		public void NotEqual1()
+		public void PositiveNotEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveNotEqual1"));
 		}

 		[Fact]
-		public void NotEqual2()
+		public void PositiveNotEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveNotEqual2"));
 		}

 		[Fact]
-		public void NotEqual3()
+		public void PositiveNotEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveNotEqual3"));
 		}

 		[Fact]
-		public void GreaterThan1()
+		public void PositiveGreaterThan1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveGreaterThan1"));
 		}

 		[Fact]
-		public void GreaterThan2()
+		public void PositiveGreaterThan2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveGreaterThan2"));
 		}

 		[Fact]
-		public void GreaterThan3()
+		public void PositiveGreaterThan3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveGreaterThan3"));
 		}

 		[Fact]
-		public void LessThan1()
+		public void PositiveLessThan1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveLessThan1"));
 		}

 		[Fact]
-		public void LessThan2()
+		public void PositiveLessThan2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveLessThan2"));
 		}

 		[Fact]
-		public void LessThan3()
+		public void PositiveLessThan3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveLessThan3"));
 		}

 		[Fact]
-		public void GreaterThanOrEqual1()
+		public void PositiveGreaterThanOrEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveGreaterThanOrEqual1"));
 		}

 		[Fact]
-		public void GreaterThanOrEqual2()
+		public void PositiveGreaterThanOrEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveGreaterThanOrEqual2"));
 		}

 		[Fact]
-		public void GreaterThanOrEqual3()
+		public void PositiveGreaterThanOrEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveGreaterThanOrEqual3"));
 		}

 		[Fact]
-		public void LessThanOrEqual1()
+		public void PositiveLessThanOrEqual1()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveLessThanOrEqual1"));
 		}

 		[Fact]
-		public void LessThanOrEqual2()
+		public void PositiveLessThanOrEqual2()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveLessThanOrEqual2"));
 		}

 		[Fact]
-		public void LessThanOrEqual3()
+		public void PositiveLessThanOrEqual3()
 		{
 			Assert.True(Run<bool>("Mosa.Test.Collection.EnumU4Class.PositiveLessThanOrEqual3"));
 		}


Refactored DbContextExtensions.ApplyChanges to mark deleted children from bottom of object graph. Apply_Changes_Should_Mark_Grandchild_Deleted now passes.

--- Source/TrackableEntities.EF.5/DbContextExtensions.cs
+++ Source/TrackableEntities.EF.5/DbContextExtensions.cs
@@ -99,9 +99,10 @@
                 return;
             }

-            // Exit if parent is deleted and not a M-1 relation
+            // Exit if item is not deleted, parent is deleted, and not a M-1 relation
             if (parent != null
-                && (parent.TrackingState == TrackingState.Deleted)
+                && item.TrackingState != TrackingState.Deleted
+                && parent.TrackingState == TrackingState.Deleted
                 && !context.IsRelatedProperty(parent.GetType(),
                     propertyName, RelationshipType.ManyToOne))
                 return;
@@ -161,7 +162,13 @@
             {
                 // Set added state for reference or child properties
                 context.ApplyChangesOnProperties(item, visitationHelper.Clone(), TrackingState.Added); // Clone to avoid interference
-
+
+                // Delete children prior to parent
+                if (item.TrackingState == TrackingState.Deleted)
+                {
+                    context.ApplyChangesOnProperties(item, visitationHelper, TrackingState.Deleted);
+                }
+
                 // Set modified properties
                 if (item.TrackingState == TrackingState.Modified
                     && (state == null || state == TrackingState.Modified)


REMOVED: Query - Unused using directive.

--- Source/UnityQuery/Assets/UnityQuery/Scripts/Query.cs
+++ Source/UnityQuery/Assets/UnityQuery/Scripts/Query.cs
@@ -9,8 +9,6 @@
     using System.Collections;
     using System.Collections.Generic;
     using System.Linq;
-
-    using UnityEngine;

     /// <summary>
     ///   Wraps a sequence of objects, forcing immediate execution of an


Update RequestExtensions.cs

Update RequestExtensions.cs

--- src/Server/WebAPI/net461/SwiftDotNet.WebAPI/SwiftDotNet.WebAPI/Extensions/RequestExtensions.cs
+++ src/Server/WebAPI/net461/SwiftDotNet.WebAPI/SwiftDotNet.WebAPI/Extensions/RequestExtensions.cs
@@ -1,12 +1,65 @@
-using System;
+using Newtonsoft.Json;
+using SwiftDotNet.WebAPI.Models;
+using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net.Http;
 using System.Text;
 using System.Threading.Tasks;
+using System.Web;

 namespace SwiftDotNet.WebAPI.Extensions
 {
-    class RequestExtensions
+    public static class RequestExtensions
     {
+        public static string GetIPWithCloudflare(this HttpRequestMessage request)
+        {
+            string userIP = request.Headers.GetValues("CF-CONNECTING-IP").FirstOrDefault() != null ? request.Headers.GetValues("CF-CONNECTING-IP").FirstOrDefault() : "127.0.0.1";
+
+            // Fallback from Cloudflare to X-Forwarded-For
+            if (userIP == "127.0.0.1")
+            {
+                userIP = request.Headers.GetValues("X-Forwarded-For").FirstOrDefault().Split(',').FirstOrDefault() != null ?
+                            request.Headers.GetValues("X-Forwarded-For").FirstOrDefault().Split(',').FirstOrDefault() :
+                            // Fallback from X-Forwarded-For to HttpContext UserHostAddress If No X-Forwarded-For
+                            (request.Properties.ContainsKey("MS_HttpContext") ? ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress : "127.0.0.1");
+            }
+
+            return userIP;
+        }
+
+        public static string GetIPWithoutCloudflare(this HttpRequestMessage request)
+        {
+
+            string userIP = request.Properties.ContainsKey("MS_HttpContext") ? ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress : "127.0.0.1";
+
+            return userIP;
+        }
+
+        public static string GetCountryCodeWithCloudflare(this HttpRequestMessage request)
+        {
+            string userCountry = request.Headers.GetValues("CF-IPCountry").FirstOrDefault() != null ? request.Headers.GetValues("CF-IPCountry").FirstOrDefault() : null;
+
+            return userCountry;
+        }
+        public static async Task<string> GetCountryCodeWithoutCloudflare(this HttpRequestMessage request)
+        {
+            var client = new HttpClient();
+
+            var userIP = GetIPWithoutCloudflare(request);
+
+            var locStr = "http://geobytes.dryverlessads.com/GetCityDetails?ipaddress=" + userIP;
+
+            Task<HttpResponseMessage> locationTask = client.GetAsync(locStr);
+            var locResult = await locationTask;
+
+            var locString = await locResult.Content.ReadAsStringAsync();
+
+            GeobytesLocation clientLocation = await JsonConvert.DeserializeObjectAsync<GeobytesLocation>(locString);
+
+            client = null;
+
+            return clientLocation.geobytescode;
+        }
     }
 }


Considering how to test Hangfire. #12

Considering how to test Hangfire. #12

- Added property required by UseHangfire method to AppBuilderFixture

--- VaraniumSharp.Monolith.Tests/Helpers/AppBuilderFixture.cs
+++ VaraniumSharp.Monolith.Tests/Helpers/AppBuilderFixture.cs
@@ -1,4 +1,5 @@
-using Owin;
+using Moq;
+using Owin;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
@@ -15,11 +16,15 @@
             var tokenSource = new CancellationTokenSource();
             Properties = new ConcurrentDictionary<string, object>();
             Properties.Add("server.OnDispose", tokenSource.Token);
+            //See http://sourcebrowser.io/Browse/jchannon/katanaproject/src/Microsoft.Owin/Extensions/AppBuilderExtensions.cs#78
+            Properties.Add("builder.AddSignatureConversion", DelegateAction);
         }

         #endregion

         #region Properties
+
+        public Action<Delegate> DelegateAction => EmptyDelegateMethod;

         public int MiddleWareRegistrationInvocations { get; private set; }

@@ -46,5 +51,14 @@
         }

         #endregion
+
+        #region Private Methods
+
+        private void EmptyDelegateMethod(Delegate @delegate)
+        {
+            //Just does nothing
+        }
+
+        #endregion
     }
 }


Add basic migration logic of key bindings to realm

--- osu.Game/OsuGameBase.cs
+++ osu.Game/OsuGameBase.cs
@@ -24,6 +24,7 @@
 using osu.Framework.Graphics.Performance;
 using osu.Framework.Graphics.Textures;
 using osu.Framework.Input;
+using osu.Framework.Input.Bindings;
 using osu.Framework.Logging;
 using osu.Game.Audio;
 using osu.Game.Database;
@@ -265,10 +266,10 @@
             dependencies.Cache(scorePerformanceManager);
             AddInternal(scorePerformanceManager);

-            // todo: migrate to realm
-            // dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore));
+            migrateDataToRealm();

             dependencies.CacheAs(KeyBindingStore = new RealmKeyBindingStore(realmFactory, RulesetStore));
+
             dependencies.Cache(SettingsStore = new SettingsStore(contextFactory));
             dependencies.Cache(RulesetConfigCache = new RulesetConfigCache(SettingsStore));
             dependencies.Cache(new SessionStatics());
@@ -322,6 +323,29 @@
             Ruleset.BindValueChanged(onRulesetChanged);
         }

+        private void migrateDataToRealm()
+        {
+            using (var db = contextFactory.GetForWrite())
+            using (var realm = realmFactory.GetForWrite())
+            {
+                var existingBindings = db.Context.DatabasedKeyBinding;
+
+                foreach (var dkb in existingBindings)
+                {
+                    realm.Context.Add(new RealmKeyBinding
+                    {
+                        ID = Guid.NewGuid().ToString(),
+                        KeyCombination = dkb.KeyCombination.ToString(),
+                        Action = (int)dkb.Action,
+                        RulesetID = dkb.RulesetID,
+                        Variant = dkb.Variant
+                    });
+                }
+
+                db.Context.RemoveRange(existingBindings);
+            }
+        }
+
         private void onRulesetChanged(ValueChangedEvent<RulesetInfo> r)
         {
             var dict = new Dictionary<ModType, IReadOnlyList<Mod>>();


Remove unnecessary inject

Remove unnecessary inject

--- osu.Game/OsuGameBase.cs
+++ osu.Game/OsuGameBase.cs
@@ -126,7 +126,6 @@
             dependencies.CacheAs<IAPIProvider>(api);

             var channelManager = new ChannelManager();
-            dependencies.Inject(channelManager);
             dependencies.Cache(channelManager);
             AddInternal(channelManager);


Ensure global beatmap/ruleset are always mutated from the update thread

This came up while testing the new realm thread, where `MusicController`
would fall over when `OsuTestScene` changes the global beatmap from an
async load thread (causing a cross-thread realm access).

We don't want to have to schedule every usage of these bindables, so
this seems like a good constraint to put in place.

--- osu.Game/OsuGameBase.cs
+++ osu.Game/OsuGameBase.cs
@@ -327,6 +327,7 @@
             dependencies.CacheAs(MusicController);

             Ruleset.BindValueChanged(onRulesetChanged);
+            Beatmap.BindValueChanged(onBeatmapChanged);
         }

         protected virtual void InitialiseFonts()
@@ -448,8 +449,17 @@

         protected override Storage CreateStorage(GameHost host, Storage defaultStorage) => new OsuStorage(host, defaultStorage);

+        private void onBeatmapChanged(ValueChangedEvent<WorkingBeatmap> valueChangedEvent)
+        {
+            if (!ThreadSafety.IsUpdateThread)
+                throw new InvalidOperationException("Global beatmap bindable must be changed from update thread.");
+        }
+
         private void onRulesetChanged(ValueChangedEvent<RulesetInfo> r)
         {
+            if (!ThreadSafety.IsUpdateThread)
+                throw new InvalidOperationException("Global ruleset bindable must be changed from update thread.");
+
             if (r.NewValue?.Available != true)
             {
                 // reject the change if the ruleset is not available.


General function reorganisation

General function reorganisation

--- osu.Game/OsuGameBase.cs
+++ osu.Game/OsuGameBase.cs
@@ -57,7 +57,33 @@

         public const int SAMPLE_CONCURRENCY = 6;

+        /// <summary>
+        /// The maximum volume at which audio tracks should playback. This can be set lower than 1 to create some head-room for sound effects.
+        /// </summary>
+        internal const double GLOBAL_TRACK_VOLUME_ADJUST = 0.5;
+
         public bool UseDevelopmentServer { get; }
+
+        public virtual Version AssemblyVersion => Assembly.GetEntryAssembly()?.GetName().Version ?? new Version();
+
+        /// <summary>
+        /// MD5 representation of the game executable.
+        /// </summary>
+        public string VersionHash { get; private set; }
+
+        public bool IsDeployedBuild => AssemblyVersion.Major > 0;
+
+        public virtual string Version
+        {
+            get
+            {
+                if (!IsDeployedBuild)
+                    return @"local " + (DebugUtils.IsDebugBuild ? @"debug" : @"release");
+
+                var version = AssemblyVersion;
+                return $@"{version.Major}.{version.Minor}.{version.Build}";
+            }
+        }

         protected OsuConfigManager LocalConfig { get; private set; }

@@ -118,32 +144,17 @@

         private MultiplayerClient multiplayerClient;

+        private DatabaseContextFactory contextFactory;
+
         protected override Container<Drawable> Content => content;

         private Container content;

+        private DependencyContainer dependencies;
+
         private Bindable<bool> fpsDisplayVisible;

-        public virtual Version AssemblyVersion => Assembly.GetEntryAssembly()?.GetName().Version ?? new Version();
-
-        /// <summary>
-        /// MD5 representation of the game executable.
-        /// </summary>
-        public string VersionHash { get; private set; }
-
-        public bool IsDeployedBuild => AssemblyVersion.Major > 0;
-
-        public virtual string Version
-        {
-            get
-            {
-                if (!IsDeployedBuild)
-                    return @"local " + (DebugUtils.IsDebugBuild ? @"debug" : @"release");
-
-                var version = AssemblyVersion;
-                return $@"{version.Major}.{version.Minor}.{version.Build}";
-            }
-        }
+        private readonly BindableNumber<double> globalTrackVolumeAdjust = new BindableNumber<double>(GLOBAL_TRACK_VOLUME_ADJUST);

         public OsuGameBase()
         {
@@ -151,23 +162,14 @@
             Name = @"osu!lazer";
         }

-        private DependencyContainer dependencies;
+        protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager();
+
+        protected virtual BatteryInfo CreateBatteryInfo() => null;
+
+        protected virtual Container CreateScalingContainer() => new DrawSizePreservingFillContainer();

         protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
             dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
-
-        private DatabaseContextFactory contextFactory;
-
-        protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager();
-
-        protected virtual BatteryInfo CreateBatteryInfo() => null;
-
-        /// <summary>
-        /// The maximum volume at which audio tracks should playback. This can be set lower than 1 to create some head-room for sound effects.
-        /// </summary>
-        internal const double GLOBAL_TRACK_VOLUME_ADJUST = 0.5;
-
-        private readonly BindableNumber<double> globalTrackVolumeAdjust = new BindableNumber<double>(GLOBAL_TRACK_VOLUME_ADJUST);

         [BackgroundDependencyLoader]
         private void load()
@@ -345,24 +347,6 @@
             Ruleset.BindValueChanged(onRulesetChanged);
         }

-        private void onRulesetChanged(ValueChangedEvent<RulesetInfo> r)
-        {
-            var dict = new Dictionary<ModType, IReadOnlyList<Mod>>();
-
-            if (r.NewValue?.Available == true)
-            {
-                foreach (ModType type in Enum.GetValues(typeof(ModType)))
-                    dict[type] = r.NewValue.CreateInstance().GetModsFor(type).ToList();
-            }
-
-            if (!SelectedMods.Disabled)
-                SelectedMods.Value = Array.Empty<Mod>();
-
-            AvailableMods.Value = dict;
-        }
-
-        protected virtual Container CreateScalingContainer() => new DrawSizePreservingFillContainer();
-
         protected override void LoadComplete()
         {
             base.LoadComplete();
@@ -376,6 +360,22 @@
             FrameStatistics.ValueChanged += e => fpsDisplayVisible.Value = e.NewValue != FrameStatisticsMode.None;
         }

+        private void onRulesetChanged(ValueChangedEvent<RulesetInfo> r)
+        {
+            var dict = new Dictionary<ModType, IReadOnlyList<Mod>>();
+
+            if (r.NewValue?.Available == true)
+            {
+                foreach (ModType type in Enum.GetValues(typeof(ModType)))
+                    dict[type] = r.NewValue.CreateInstance().GetModsFor(type).ToList();
+            }
+
+            if (!SelectedMods.Disabled)
+                SelectedMods.Value = Array.Empty<Mod>();
+
+            AvailableMods.Value = dict;
+        }
+
         private void runMigrations()
         {
             try


Source hash from osu.Game.dll rather than executable

--- osu.Game/OsuGameBase.cs
+++ osu.Game/OsuGameBase.cs
@@ -134,13 +134,8 @@
         [BackgroundDependencyLoader]
         private void load()
         {
-            var assembly = Assembly.GetEntryAssembly();
-
-            if (assembly != null)
-            {
-                using (var str = File.OpenRead(assembly.Location))
-                    VersionHash = str.ComputeMD5Hash();
-            }
+            using (var str = File.OpenRead(typeof(OsuGameBase).Assembly.Location))
+                VersionHash = str.ComputeMD5Hash();

             Resources.AddStore(new DllResourceStore(OsuResources.ResourceAssembly));


[Rust] Switch to Covalence and add permissions for commands

Permissions:

oxide.plugins
oxide.load
oxide.reload
oxide.unload
oxide.grant
oxide.group
oxide.revoke
oxide.show
oxide.usergroup

--- Games/Unity/Oxide.Game.Rust/RustCore.cs
+++ Games/Unity/Oxide.Game.Rust/RustCore.cs
@@ -8,6 +8,7 @@
 using Network;
 using Oxide.Core;
 using Oxide.Core.Libraries;
+using Oxide.Core.Libraries.Covalence;
 using Oxide.Core.Plugins;
 using Oxide.Core.ServerConsole;
 using Oxide.Game.Rust.Libraries;
@@ -62,6 +63,7 @@
             {"GroupPermissionGranted", "Group '{0}' granted permission '{1}'"},
             {"GroupPermissionRevoked", "Group '{0}' revoked permission '{1}'"},
             {"NoPluginsFound", "No plugins are currently available"},
+            {"NotAllowed", "You are not allowed to use the '{0}' command"},
             {"PermissionNotFound", "Permission '{0}' doesn't exist"},
             {"PermissionsNotLoaded", "Unable to load permission files! Permissions will not work until resolved.\n => {0}"},
             {"PlayerLanguage", "Player language set to {0}"},
@@ -117,11 +119,12 @@
         /// <summary>
         /// Checks if the permission system has loaded, shows an error if it failed to load
         /// </summary>
-        /// <returns></returns>
-        private bool PermissionsLoaded(ConsoleSystem.Arg arg)
+        /// <param name="player"></param>
+        /// <returns></returns>
+        private bool PermissionsLoaded(IPlayer player)
         {
             if (permission.IsLoaded) return true;
-            Reply(arg, "PermissionsNotLoaded", permission.LastException.Message);
+            player.Reply(lang.GetMessage("PermissionsNotLoaded", this, player.Id), permission.LastException.Message);
             return false;
         }

@@ -142,35 +145,33 @@
             // Register messages for localization
             lang.RegisterMessages(messages, this);

-            // Add general commands
-            cmdlib.AddConsoleCommand("oxide.plugins", this, "ConsolePlugins");
-            cmdlib.AddConsoleCommand("global.plugins", this, "ConsolePlugins");
-            cmdlib.AddConsoleCommand("oxide.load", this, "ConsoleLoad");
-            cmdlib.AddConsoleCommand("global.load", this, "ConsoleLoad");
-            cmdlib.AddConsoleCommand("oxide.unload", this, "ConsoleUnload");
-            cmdlib.AddConsoleCommand("global.unload", this, "ConsoleUnload");
-            cmdlib.AddChatCommand("reload", this, "ChatReload");
-            cmdlib.AddConsoleCommand("oxide.reload", this, "ConsoleReload");
-            cmdlib.AddConsoleCommand("global.reload", this, "ConsoleReload");
-            cmdlib.AddChatCommand("version", this, "ChatVersion");
-            cmdlib.AddChatCommand("oxide.version", this, "ChatVersion");
-            cmdlib.AddConsoleCommand("version", this, "ConsoleVersion");
-            cmdlib.AddConsoleCommand("oxide.version", this, "ConsoleVersion");
-            cmdlib.AddChatCommand("lang", this, "ChatLang");
-            cmdlib.AddConsoleCommand("oxide.lang", this, "ConsoleLang");
-            cmdlib.AddConsoleCommand("global.lang", this, "ConsoleLang");
-
-            // Add permission commands
-            cmdlib.AddConsoleCommand("oxide.group", this, "ConsoleGroup");
-            cmdlib.AddConsoleCommand("global.group", this, "ConsoleGroup");
-            cmdlib.AddConsoleCommand("oxide.usergroup", this, "ConsoleUserGroup");
-            cmdlib.AddConsoleCommand("global.usergroup", this, "ConsoleUserGroup");
-            cmdlib.AddConsoleCommand("oxide.grant", this, "ConsoleGrant");
-            cmdlib.AddConsoleCommand("global.grant", this, "ConsoleGrant");
-            cmdlib.AddConsoleCommand("oxide.revoke", this, "ConsoleRevoke");
-            cmdlib.AddConsoleCommand("global.revoke", this, "ConsoleRevoke");
-            cmdlib.AddConsoleCommand("oxide.show", this, "ConsoleShow");
-            cmdlib.AddConsoleCommand("global.show", this, "ConsoleShow");
+            // Add core general commands
+            AddCovalenceCommand(new[] { "oxide.version", "version" }, "VersionCommand");
+            AddCovalenceCommand(new[] { "oxide.lang", "lang" }, "LangCommand");
+
+            // Add core plugin commands
+            AddCovalenceCommand(new[] { "oxide.plugins", "plugins" }, "PluginsCommand");
+            AddCovalenceCommand(new[] { "oxide.load", "load" }, "LoadCommand");
+            AddCovalenceCommand(new[] { "oxide.reload", "reload" }, "ReloadCommand");
+            AddCovalenceCommand(new[] { "oxide.unload", "unload" }, "UnloadCommand");
+
+            // Add core permission commands
+            AddCovalenceCommand(new[] { "oxide.grant", "grant" }, "GrantCommand");
+            AddCovalenceCommand(new[] { "oxide.group", "group" }, "GroupCommand");
+            AddCovalenceCommand(new[] { "oxide.revoke", "revoke" }, "RevokeCommand");
+            AddCovalenceCommand(new[] { "oxide.show", "show" }, "ShowCommand");
+            AddCovalenceCommand(new[] { "oxide.usergroup", "usergroup" }, "UsergroupCommand");
+
+            // Register core permissions
+            permission.RegisterPermission("oxide.plugins", this);
+            permission.RegisterPermission("oxide.load", this);
+            permission.RegisterPermission("oxide.reload", this);
+            permission.RegisterPermission("oxide.unload", this);
+            permission.RegisterPermission("oxide.grant", this);
+            permission.RegisterPermission("oxide.group", this);
+            permission.RegisterPermission("oxide.revoke", this);
+            permission.RegisterPermission("oxide.show", this);
+            permission.RegisterPermission("oxide.usergroup", this);

             // Setup the default permission groups
             if (permission.IsLoaded)
@@ -567,17 +568,24 @@

         #endregion

-        #region Chat/Console Commands
+        #region Covalence Commands

         #region Plugins Command

         /// <summary>
         /// Called when the "plugins" command has been executed
         /// </summary>
-        [HookMethod("ConsolePlugins")]
-        private void ConsolePlugins(ConsoleSystem.Arg arg)
-        {
-            if (!IsAdmin(arg.Player())) return;
+        /// <param name="player"></param>
+        /// <param name="command"></param>
+        /// <param name="args"></param>
+        [HookMethod("PluginsCommand")]
+        private void PluginsCommand(IPlayer player, string command, string[] args)
+        {
+            if (!player.IsAdmin || player.HasPermission("oxide.plugins"))
+            {
+                player.Reply(lang.GetMessage("NotAllowed", this, player.Id), command);
+                return;
+            }

             var loadedPlugins = pluginManager.GetPlugins().Where(pl => !pl.IsCorePlugin).ToArray();
             var loadedPluginNames = new HashSet<string>(loadedPlugins.Select(pl => pl.Name));
@@ -594,7 +602,7 @@
             var totalPluginCount = loadedPlugins.Length + unloadedPluginErrors.Count;
             if (totalPluginCount < 1)
             {
-                Reply(arg, "NoPluginsFound");
+                player.Reply(lang.GetMessage("NoPluginsFound", this, player.Id));
                 return;
             }

@@ -604,7 +612,7 @@
                 output += $"\n  {number++:00} \"{plugin.Title}\" ({plugin.Version}) by {plugin.Author} ({plugin.TotalHookTime:0.00}s)";
             foreach (var pluginName in unloadedPluginErrors.Keys)
                 output += $"\n  {number++:00} {pluginName} - {unloadedPluginErrors[pluginName]}";
-            arg.ReplyWith(output);
+            player.Reply(output);
         }

         #endregion
@@ -614,24 +622,31 @@
         /// <summary>
         /// Called when the "load" command has been executed
         /// </summary>
-        /// <param name="arg"></param>
-        [HookMethod("ConsoleLoad")]
-        private void ConsoleLoad(ConsoleSystem.Arg arg)
-        {
-            if (!IsAdmin(arg.Player())) return;
-            if (!arg.HasArgs())
-            {
-                Reply(arg, "CommandUsageLoad");
-                return;
-            }
-
-            if (arg.GetString(0).Equals("*"))
+        /// <param name="player"></param>
+        /// <param name="command"></param>
+        /// <param name="args"></param>
+        [HookMethod("LoadCommand")]
+        private void LoadCommand(IPlayer player, string command, string[] args)
+        {
+            if (!player.IsAdmin || player.HasPermission("oxide.load"))
+            {
+                player.Reply(lang.GetMessage("NotAllowed", this, player.Id), command);
+                return;
+            }
+
+            if (args.Length < 1)
+            {
+                player.Reply(lang.GetMessage("CommandUsageLoad", this, player.Id));
+                return;
+            }
+
+            if (args[0].Equals("*") || args[0].Equals("all"))
             {
                 Interface.Oxide.LoadAllPlugins();
                 return;
             }

-            foreach (var name in arg.Args)
+            foreach (var name in args)
             {
                 if (string.IsNullOrEmpty(name)) continue;
                 Interface.Oxide.LoadPlugin(name);
@@ -644,22 +659,27 @@
         #region Reload Command

         /// <summary>
-        /// Called when the "reload" chat command has been executed
+        /// Called when the "reload" command has been executed
         /// </summary>
         /// <param name="player"></param>
         /// <param name="command"></param>
         /// <param name="args"></param>
-        [HookMethod("ChatReload")]
-        private void ChatReload(BasePlayer player, string command, string[] args)
-        {
-            if (!IsAdmin(player)) return;
-            if (args.Length == 0)
-            {
-                Reply(player, "CommandUsageReload");
-                return;
-            }
-
-            if (args[0].Equals("*"))
+        [HookMethod("ReloadCommand")]
+        private void ReloadCommand(IPlayer player, string command, string[] args)
+        {
+            if (!player.IsAdmin || player.HasPermission("oxide.reload"))
+            {
+                player.Reply(lang.GetMessage("NotAllowed", this, player.Id), command);
+                return;
+            }
+
+            if (args.Length < 1)
+            {
+                player.Reply(lang.GetMessage("CommandUsageReload", this, player.Id));
+                return;
+            }
+
+            if (args[0].Equals("*") || args[0].Equals("all"))
             {
                 Interface.Oxide.ReloadAllPlugins();
                 return;
@@ -669,116 +689,91 @@
                 if (!string.IsNullOrEmpty(name)) Interface.Oxide.ReloadPlugin(name);
         }

-        /// <summary>
-        /// Called when the "reload" console command has been executed
-        /// </summary>
-        /// <param name="arg"></param>
-        [HookMethod("ConsoleReload")]
-        private void ConsoleReload(ConsoleSystem.Arg arg)
-        {
-            if (!IsAdmin(arg.Player())) return;
-            if (!arg.HasArgs())
-            {
-                Reply(arg, "CommandUsageReload");
-                return;
-            }
-
-            if (arg.GetString(0).Equals("*"))
-            {
-                Interface.Oxide.ReloadAllPlugins();
-                return;
-            }
-
-            foreach (var name in arg.Args)
-                if (!string.IsNullOrEmpty(name)) Interface.Oxide.ReloadPlugin(name);
-        }
-
         #endregion

         #region Unload Command

         /// <summary>
         /// Called when the "unload" command has been executed
-        /// </summary>
-        /// <param name="arg"></param>
-        [HookMethod("ConsoleUnload")]
-        private void ConsoleUnload(ConsoleSystem.Arg arg)
-        {
-            if (!IsAdmin(arg.Player())) return;
-            if (!arg.HasArgs())
-            {
-                Reply(arg, "CommandUsageUnload");
-                return;
-            }
-
-            if (arg.GetString(0).Equals("*"))
-            {
-                Interface.Oxide.UnloadAllPlugins();
-                return;
-            }
-
-            foreach (var name in arg.Args)
-                if (!string.IsNullOrEmpty(name)) Interface.Oxide.UnloadPlugin(name);
-        }
-
-        #endregion
-
-        #region Version Command
-
-        /// <summary>
-        /// Called when the "oxide.version" chat command has been executed
-        /// </summary>
-        /// <param name="player"></param>
-        [HookMethod("ChatVersion")]
-        private void ChatVersion(BasePlayer player)
-        {
-            Reply(player, $"Oxide {OxideMod.Version} for {Title} {BuildInformation.VersionStampDays} ({Protocol.network})");
-        }
-
-        /// <summary>
-        /// Called when the "oxide.version" console command has been executed
-        /// </summary>
-        [HookMethod("ConsoleVersion")]
-        private void ConsoleVersion(ConsoleSystem.Arg arg)
-        {
-            if (arg.cmd.namefull == "oxide.version")
-                Reply(arg, $"Oxide {OxideMod.Version} for {Title} {BuildInformation.VersionStampDays} ({Protocol.network})");
-            else if (arg.cmd.namefull == "global.version")
-                Reply(arg, $"Protocol: {Protocol.printable}\nBuild Version: {BuildInformation.VersionStampDays}\nBuild Date: {BuildInformation.VersionStampString}\nUnity Version: {UnityEngine.Application.unityVersion}\nChangeset: {BuildInformation.ChangeSet}\nBranch: {BuildInformation.BranchName}\nOxide Version: {OxideMod.Version}");
-        }
-
-        #endregion
-
-        #region Lang Command
-
-        /// <summary>
-        /// Called when the "lang" chat command has been executed
         /// </summary>
         /// <param name="player"></param>
         /// <param name="command"></param>
         /// <param name="args"></param>
-        [HookMethod("ChatLang")]
-        private void ChatLang(BasePlayer player, string command, string[] args)
-        {
-            if (args != null && args.Length > 0) lang.SetLanguage(args[0], player.UserIDString);
-            Reply(player, "PlayerLanguage", lang.GetLanguage(player.UserIDString));
-
-            Analytics.Event("Commands", "Lang command use via chat");
-        }
-
-        /// <summary>
-        /// Called when the "lang" console command has been executed
-        /// </summary>
-        /// <param name="arg"></param>
-        [HookMethod("ConsoleLang")]
-        private void ConsoleLang(ConsoleSystem.Arg arg)
-        {
-            if (!IsAdmin(arg.Player())) return;
-
-            if (arg.HasArgs()) lang.SetServerLanguage(arg.GetString(0));
-            Reply(arg, "ServerLanguage", lang.GetServerLanguage());
-
-            Analytics.Event("Commands", "Lang command use via console");
+        [HookMethod("UnloadCommand")]
+        private void UnloadCommand(IPlayer player, string command, string[] args)
+        {
+            if (!player.IsAdmin || player.HasPermission("oxide.unload"))
+            {
+                player.Reply(lang.GetMessage("NotAllowed", this, player.Id));
+                return;
+            }
+
+            if (args.Length < 1)
+            {
+                player.Reply(lang.GetMessage("CommandUsageUnload", this, player.Id));
+                return;
+            }
+
+            if (args[0].Equals("*") || args[0].Equals("all"))
+            {
+                Interface.Oxide.UnloadAllPlugins();
+                return;
+            }
+
+            foreach (var name in args)
+                if (!string.IsNullOrEmpty(name)) Interface.Oxide.UnloadPlugin(name);
+        }
+
+        #endregion
+
+        #region Version Command
+
+        /// <summary>
+        /// Called when the "version" command has been executed
+        /// </summary>
+        /// <param name="player"></param>
+        /// <param name="command"></param>
+        /// <param name="args"></param>
+        [HookMethod("VersionCommand")]
+        private void VersionCommand(IPlayer player, string command, string[] args)
+        {
+            if (command == "oxide.version")
+                player.Reply($"Oxide {OxideMod.Version} for {Title} {BuildInformation.VersionStampDays} ({Protocol.network})");
+            else if (command == "version")
+                player.Reply($"Protocol: {Protocol.printable}\nBuild Version: {BuildInformation.VersionStampDays}\n" +
+                             $"Build Date: {BuildInformation.VersionStampString}\nUnity Version: {UnityEngine.Application.unityVersion}\n" +
+                             $"Changeset: {BuildInformation.ChangeSet}\nBranch: {BuildInformation.BranchName}\nOxide Version: {OxideMod.Version}");
+        }
+
+        #endregion
+
+        #region Lang Command
+
+        /// <summary>
+        /// Called when the "lang" command has been executed
+        /// </summary>
+        /// <param name="player"></param>
+        /// <param name="command"></param>
+        /// <param name="args"></param>
+        [HookMethod("LangCommand")]
+        private void LangCommand(IPlayer player, string command, string[] args)
+        {
+            if (args.Length < 1)
+            {
+                player.Reply(lang.GetMessage("CommandUsageGroup", this, player.Id));
+                return;
+            }
+
+            if (player.Id != "server_console")
+            {
+                lang.SetLanguage(args[0], player.Id);
+                player.Reply(lang.GetMessage("PlayerLanguage", this, player.Id), args[0]);
+            }
+            else
+            {
+                lang.SetServerLanguage(args[0]);
+                player.Reply(lang.GetMessage("ServerLanguage", this, player.Id), lang.GetServerLanguage());
+            }
         }

         #endregion
@@ -788,125 +783,139 @@
         /// <summary>
         /// Called when the "group" command has been executed
         /// </summary>
-        /// <param name="arg"></param>
-        [HookMethod("ConsoleGroup")]
-        private void ConsoleGroup(ConsoleSystem.Arg arg)
-        {
-            if (!PermissionsLoaded(arg)) return;
-            if (!IsAdmin(arg.Player())) return;
-            if (!arg.HasArgs(2))
-            {
-                Reply(arg, "CommandUsageGroup");
-                return;
-            }
-
-            var mode = arg.GetString(0);
-            var group = arg.GetString(1);
+        /// <param name="player"></param>
+        /// <param name="command"></param>
+        /// <param name="args"></param>
+        [HookMethod("GroupCommand")]
+        private void GroupCommand(IPlayer player, string command, string[] args)
+        {
+            if (!PermissionsLoaded(player)) return;
+            if (!player.IsAdmin || player.HasPermission("oxide.group"))
+            {
+                player.Reply(lang.GetMessage("NotAllowed", this, player.Id), command);
+                return;
+            }
+
+            if (args.Length != 2)
+            {
+                player.Reply(lang.GetMessage("CommandUsageGroup", this, player.Id));
+                return;
+            }
+
+            var mode = args[0];
+            var group = args[1];

             if (mode.Equals("add"))
             {
                 if (permission.GroupExists(group))
                 {
-                    Reply(arg, "GroupAlreadyExists", group);
+                    player.Reply(lang.GetMessage("GroupAlreadyExists", this, player.Id), group);
                     return;
                 }
-                permission.CreateGroup(group, arg.GetString(2), arg.GetInt(3));
-                Reply(arg, "GroupCreated", group);
+                permission.CreateGroup(group, args[2], int.Parse(args[3]));
+                player.Reply(lang.GetMessage("GroupCreated", this, player.Id), group);
             }
             else if (mode.Equals("remove"))
             {
                 if (!permission.GroupExists(group))
                 {
-                    Reply(arg, "GroupNotFound", group);
+                    player.Reply(lang.GetMessage("GroupNotFound", this, player.Id), group);
                     return;
                 }
                 permission.RemoveGroup(group);
-                Reply(arg, "GroupDeleted", group);
+                player.Reply(lang.GetMessage("GroupDeleted", this, player.Id), group);
             }
             else if (mode.Equals("set"))
             {
                 if (!permission.GroupExists(group))
                 {
-                    Reply(arg, "GroupNotFound", group);
+                    player.Reply(lang.GetMessage("GroupNotFound", this, player.Id), group);
                     return;
                 }
-                permission.SetGroupTitle(group, arg.GetString(2));
-                permission.SetGroupRank(group, arg.GetInt(3));
-                Reply(arg, "GroupChanged", group);
+                permission.SetGroupTitle(group, args[2]);
+                permission.SetGroupRank(group, int.Parse(args[3]));
+                player.Reply(lang.GetMessage("GroupChanged", this, player.Id), group);
             }
             else if (mode.Equals("parent"))
             {
                 if (!permission.GroupExists(group))
                 {
-                    Reply(arg, "GroupNotFound", group);
+                    player.Reply(lang.GetMessage("GroupNotFound", this, player.Id), group);
                     return;
                 }
-                var parent = arg.GetString(2);
+                var parent = args[2];
                 if (!string.IsNullOrEmpty(parent) && !permission.GroupExists(parent))
                 {
-                    Reply(arg, "GroupParentNotFound", parent);
+                    player.Reply(lang.GetMessage("GroupParentNotFound", this, player.Id), parent);
                     return;
                 }
                 if (permission.SetGroupParent(group, parent))
-                    Reply(arg, "GroupParentChanged", group, parent);
+                    player.Reply(lang.GetMessage("GroupParentChanged", this, player.Id), group, parent);
                 else
-                    Reply(arg, "GroupParentNotChanged", group);
-            }
-        }
-
-        #endregion
-
-        #region User Group Command
-
-        /// <summary>
-        /// Called when the "group" command has been executed
-        /// </summary>
-        /// <param name="arg"></param>
-        [HookMethod("ConsoleUserGroup")]
-        private void ConsoleUserGroup(ConsoleSystem.Arg arg)
-        {
-            if (!PermissionsLoaded(arg)) return;
-            if (!IsAdmin(arg.Player())) return;
-            if (!arg.HasArgs(3))
-            {
-                Reply(arg, "CommandUsageUserGroup");
-                return;
-            }
-
-            var mode = arg.GetString(0);
-            var name = arg.GetString(1);
-            var group = arg.GetString(2);
-
-            var player = FindPlayer(name);
-            if (player == null && !permission.UserIdValid(name))
-            {
-                Reply(arg, "UserNotFound", name);
+                    player.Reply(lang.GetMessage("GroupParentNotChanged", this, player.Id), group);
+            }
+        }
+
+        #endregion
+
+        #region Usergroup Command
+
+        /// <summary>
+        /// Called when the "usergroup" command has been executed
+        /// </summary>
+        /// <param name="player"></param>
+        /// <param name="command"></param>
+        /// <param name="args"></param>
+        [HookMethod("UsergroupCommand")]
+        private void UsergroupCommand(IPlayer player, string command, string[] args)
+        {
+            if (!PermissionsLoaded(player)) return;
+            if (!player.IsAdmin || player.HasPermission("oxide.usergroup"))
+            {
+                player.Reply(lang.GetMessage("NotAllowed", this, player.Id), command);
+                return;
+            }
+
+            if (args.Length != 3)
+            {
+                player.Reply(lang.GetMessage("CommandUsageUserGroup", this, player.Id));
+                return;
+            }
+
+            var mode = args[0];
+            var name = args[1];
+            var group = args[2];
+
+            var target = Covalence.PlayerManager.FindPlayer(name);
+            if (target == null && !permission.UserIdValid(name))
+            {
+                player.Reply(lang.GetMessage("UserNotFound", this, player.Id), name);
                 return;
             }
             var userId = name;
-            if (player != null)
-            {
-                userId = player.UserIDString;
-                name = player.displayName;
+            if (target != null)
+            {
+                userId = target.Id;
+                name = target.Name;
                 permission.UpdateNickname(userId, name);
                 name += $"({userId})";
             }

             if (!permission.GroupExists(group))
             {
-                Reply(arg, "GroupNotFound", group);
+                player.Reply(lang.GetMessage("GroupNotFound", this, player.Id), group);
                 return;
             }

             if (mode.Equals("add"))
             {
                 permission.AddUserGroup(userId, group);
-                Reply(arg, "UserAddedToGroup", name, group);
+                player.Reply(lang.GetMessage("UserAddedToGroup", this, player.Id), name, group);
             }
             else if (mode.Equals("remove"))
             {
                 permission.RemoveUserGroup(userId, group);
-                Reply(arg, "UserRemovedFromGroup", name, group);
+                player.Reply(lang.GetMessage("UserRemovedFromGroup", this, player.Id), name, group);
             }
         }

@@ -917,25 +926,32 @@
         /// <summary>
         /// Called when the "grant" command has been executed
         /// </summary>
-        /// <param name="arg"></param>
-        [HookMethod("ConsoleGrant")]
-        private void ConsoleGrant(ConsoleSystem.Arg arg)
-        {
-            if (!PermissionsLoaded(arg)) return;
-            if (!IsAdmin(arg.Player())) return;
-            if (!arg.HasArgs(3))
-            {
-                Reply(arg, "CommandUsageGrant");
-                return;
-            }
-
-            var mode = arg.GetString(0);
-            var name = arg.GetString(1);
-            var perm = arg.GetString(2);
+        /// <param name="player"></param>
+        /// <param name="command"></param>
+        /// <param name="args"></param>
+        [HookMethod("GrantCommand")]
+        private void GrantCommand(IPlayer player, string command, string[] args)
+        {
+            if (!PermissionsLoaded(player)) return;
+            if (!player.IsAdmin || player.HasPermission("oxide.grant"))
+            {
+                player.Reply(lang.GetMessage("NotAllowed", this, player.Id), command);
+                return;
+            }
+
+            if (args.Length != 3)
+            {
+                player.Reply(lang.GetMessage("CommandUsageGrant", this, player.Id));
+                return;
+            }
+
+            var mode = args[0];
+            var name = args[1];
+            var perm = args[2];

             if (!permission.PermissionExists(perm))
             {
-                Reply(arg, "PermissionNotFound", perm);
+                player.Reply(lang.GetMessage("PermissionNotFound", this, player.Id), perm);
                 return;
             }

@@ -943,29 +959,29 @@
             {
                 if (!permission.GroupExists(name))
                 {
-                    Reply(arg, "GroupNotFound", name);
+                    player.Reply(lang.GetMessage("GroupNotFound", this, player.Id), name);
                     return;
                 }
                 permission.GrantGroupPermission(name, perm, null);
-                Reply(arg, "GroupPermissionGranted", name, perm);
+                player.Reply(lang.GetMessage("GroupPermissionGranted", this, player.Id), name, perm);
             }
             else if (mode.Equals("user"))
             {
-                var player = FindPlayer(name);
-                if (player == null && !permission.UserIdValid(name))
-                {
-                    Reply(arg, "UserNotFound", name);
+                var target = Covalence.PlayerManager.FindPlayer(name);
+                if (target == null && !permission.UserIdValid(name))
+                {
+                    player.Reply(lang.GetMessage("UserNotFound", this, player.Id), name);
                     return;
                 }
                 var userId = name;
-                if (player != null)
-                {
-                    userId = player.UserIDString;
-                    name = player.displayName;
+                if (target != null)
+                {
+                    userId = target.Id;
+                    name = target.Name;
                     permission.UpdateNickname(userId, name);
                 }
                 permission.GrantUserPermission(userId, perm, null);
-                Reply(arg, "UserPermissionGranted", $"{name} ({userId})", perm);
+                player.Reply(lang.GetMessage("UserPermissionGranted", this, player.Id), $"{name} ({userId})", perm);
             }
         }

@@ -976,25 +992,32 @@
         /// <summary>
         /// Called when the "revoke" command has been executed
         /// </summary>
-        /// <param name="arg"></param>
-        [HookMethod("ConsoleRevoke")]
-        private void ConsoleRevoke(ConsoleSystem.Arg arg)
-        {
-            if (!PermissionsLoaded(arg)) return;
-            if (!IsAdmin(arg.Player())) return;
-            if (!arg.HasArgs(3))
-            {
-                Reply(arg, "CommandUsageRevoke");
-                return;
-            }
-
-            var mode = arg.GetString(0);
-            var name = arg.GetString(1);
-            var perm = arg.GetString(2);
+        /// <param name="player"></param>
+        /// <param name="command"></param>
+        /// <param name="args"></param>
+        [HookMethod("RevokeCommand")]
+        private void RevokeCommand(IPlayer player, string command, string[] args)
+        {
+            if (!PermissionsLoaded(player)) return;
+            if (!player.IsAdmin || player.HasPermission("oxide.revoke"))
+            {
+                player.Reply(lang.GetMessage("NotAllowed", this, player.Id), command);
+                return;
+            }
+
+            if (args.Length != 3)
+            {
+                player.Reply(lang.GetMessage("CommandUsageRevoke", this, player.Id));
+                return;
+            }
+
+            var mode = args[0];
+            var name = args[1];
+            var perm = args[2];

             if (!permission.PermissionExists(perm))
             {
-                Reply(arg, "PermissionNotFound", perm);
+                player.Reply(lang.GetMessage("PermissionNotFound", this, player.Id), perm);
                 return;
             }

@@ -1002,29 +1025,29 @@
             {
                 if (!permission.GroupExists(name))
                 {
-                    Reply(arg, "GroupNotFound", name);
+                    player.Reply(lang.GetMessage("GroupNotFound", this, player.Id), name);
                     return;
                 }
                 permission.RevokeGroupPermission(name, perm);
-                Reply(arg, "GroupPermissionRevoked", name, perm);
+                player.Reply(lang.GetMessage("GroupPermissionRevoked", this, player.Id), name, perm);
             }
             else if (mode.Equals("user"))
             {
-                var player = FindPlayer(name);
-                if (player == null && !permission.UserIdValid(name))
-                {
-                    Reply(arg, "UserNotFound", name);
+                var target = Covalence.PlayerManager.FindPlayer(name);
+                if (target == null && !permission.UserIdValid(name))
+                {
+                    player.Reply(lang.GetMessage("UserNotFound", this, player.Id), name);
                     return;
                 }
                 var userId = name;
-                if (player != null)
-                {
-                    userId = player.UserIDString;
-                    name = player.displayName;
+                if (target != null)
+                {
+                    userId = target.Id;
+                    name = target.Name;
                     permission.UpdateNickname(userId, name);
                 }
                 permission.RevokeUserPermission(userId, perm);
-                Reply(arg, "UserPermissionRevoked", $"{name} ({userId})", perm);
+                player.Reply(lang.GetMessage("UserPermissionRevoked", this, player.Id), $"{name} ({userId})", perm);
             }
         }

@@ -1035,30 +1058,37 @@
         /// <summary>
         /// Called when the "show" command has been executed
         /// </summary>
-        /// <param name="arg"></param>
-        [HookMethod("ConsoleShow")]
-        private void ConsoleShow(ConsoleSystem.Arg arg)
-        {
-            if (!PermissionsLoaded(arg)) return;
-            if (!IsAdmin(arg.Player())) return;
-            if (!arg.HasArgs())
-            {
-                Reply(arg, "CommandUsageShow");
-                return;
-            }
-
-            var mode = arg.GetString(0);
-            var name = arg.GetString(1);
+        /// <param name="player"></param>
+        /// <param name="command"></param>
+        /// <param name="args"></param>
+        [HookMethod("ShowCommand")]
+        private void ShowCommand(IPlayer player, string command, string[] args)
+        {
+            if (!PermissionsLoaded(player)) return;
+            if (!player.IsAdmin || player.HasPermission("oxide.show"))
+            {
+                player.Reply(lang.GetMessage("NotAllowed", this, player.Id), command);
+                return;
+            }
+
+            if (args.Length == 0)
+            {
+                player.Reply(lang.GetMessage("CommandUsageShow", this, player.Id));
+                return;
+            }
+
+            var mode = args[0];
+            var name = args[1];

             if (mode.Equals("perms"))
             {
-                arg.ReplyWith("Permissions:\n" + string.Join(", ", permission.GetPermissions()));
+                player.Reply("Permissions:\n" + string.Join(", ", permission.GetPermissions())); // TODO: Localization
             }
             else if (mode.Equals("perm"))
             {
                 if (string.IsNullOrEmpty(name))
                 {
-                    Reply(arg, "CommandUsageShow");
+                    player.Reply(lang.GetMessage("CommandUsageShow", this, player.Id));
                     return;
                 }

@@ -1066,27 +1096,27 @@
                 result += string.Join(", ", permission.GetPermissionUsers(name));
                 result += $"\nPermission '{name}' Groups:\n";
                 result += string.Join(", ", permission.GetPermissionGroups(name));
-                arg.ReplyWith(result);
+                player.Reply(result);
             }
             else if (mode.Equals("user"))
             {
                 if (string.IsNullOrEmpty(name))
                 {
-                    Reply(arg, "CommandUsageShow");
+                    player.Reply(lang.GetMessage("CommandUsageShow", this, player.Id));
                     return;
                 }

-                var target = FindPlayer(name);
+                var target = Covalence.PlayerManager.FindPlayer(name);
                 if (target == null && !permission.UserIdValid(name))
                 {
-                    Reply(arg, "UserNotFound", name);
+                    player.Reply(lang.GetMessage("UserNotFound", this, player.Id), name);
                     return;
                 }
                 var userId = name;
                 if (target != null)
                 {
-                    userId = target.UserIDString;
-                    name = target.displayName;
+                    userId = target.Id;
+                    name = target.Name;
                     permission.UpdateNickname(userId, name);
                     name += $" ({userId})";
                 }
@@ -1094,19 +1124,19 @@
                 result += string.Join(", ", permission.GetUserPermissions(userId));
                 result += $"\nUser '{name}' groups:\n";
                 result += string.Join(", ", permission.GetUserGroups(userId));
-                arg.ReplyWith(result);
+                player.Reply(result);
             }
             else if (mode.Equals("group"))
             {
                 if (string.IsNullOrEmpty(name))
                 {
-                    Reply(arg, "CommandUsageShow");
+                    player.Reply(lang.GetMessage("CommandUsageShow", this, player.Id));
                     return;
                 }

                 if (!permission.GroupExists(name))
                 {
-                    Reply(arg, "GroupNotFound", name);
+                    player.Reply(lang.GetMessage("GroupNotFound", this, player.Id), name);
                     return;
                 }

@@ -1121,11 +1151,11 @@
                     result += string.Join(", ", permission.GetGroupPermissions(parent));
                     parent = permission.GetGroupParent(parent);
                 }
-                arg.ReplyWith(result);
+                player.Reply(result);
             }
             else if (mode.Equals("groups"))
             {
-                arg.ReplyWith("Groups:\n" + string.Join(", ", permission.GetGroups()));
+                player.Reply("Groups:\n" + string.Join(", ", permission.GetGroups())); // TODO: Localization
             }
         }

@@ -1182,7 +1212,7 @@
             if (player == null)
                 Interface.Oxide.LogDebug("Player is actually a {0}!", arg.connection.player.GetType());
             else if (!cmdlib.HandleChatCommand(player, cmd, args))
-                Reply(player, "UnknownCommand", cmd);
+                iplayer.Reply(lang.GetMessage("UnknownCommand", this, iplayer.Id), cmd);

             // Handled
             arg.ReplyWith(string.Empty);
@@ -1249,35 +1279,6 @@
         #region Helpers

         /// <summary>
-        /// Returns if specified player is admin
-        /// </summary>
-        /// <param name="player"></param>
-        /// <returns></returns>
-        private static bool IsAdmin(BasePlayer player) => player == null || player.net.connection.authLevel >= 2;
-
-        /// <summary>
-        /// Replies to the player with a specific message
-        /// </summary>
-        /// <param name="arg"></param>
-        /// <param name="key"></param>
-        /// <param name="args"></param>
-        private void Reply(ConsoleSystem.Arg arg, string key, params object[] args)
-        {
-            arg.ReplyWith(string.Format(lang.GetMessage(key, this, arg.connection?.userid.ToString()), args));
-        }
-
-        /// <summary>
-        /// Replies to the player with a specific message
-        /// </summary>
-        /// <param name="player"></param>
-        /// <param name="key"></param>
-        /// <param name="args"></param>
-        private void Reply(BasePlayer player, string key, params object[] args)
-        {
-            player.ChatMessage(string.Format(lang.GetMessage(key, this, player.UserIDString), args));
-        }
-
-        /// <summary>
         /// Returns the BasePlayer for the specified name, ID, or IP address string
         /// </summary>
         /// <param name="nameOrIdOrIp"></param>


React to Logging changes

React to Logging changes

--- test/Kestrel.FunctionalTests/EventSourceTests.cs
+++ test/Kestrel.FunctionalTests/EventSourceTests.cs
@@ -15,7 +15,7 @@

 namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
 {
-    public class EventSourceTests : LoggedTest, IDisposable
+    public class EventSourceTests : LoggedTest
     {
         private readonly TestEventListener _listener = new TestEventListener();

@@ -104,7 +104,7 @@
             }
         }

-        public void Dispose()
+        public override void Dispose()
         {
             _listener.Dispose();
         }


Fix appointments created to current DateTime

--- TestAppUWP/Samples/Calendar/CalendarExplorer.xaml.cs
+++ TestAppUWP/Samples/Calendar/CalendarExplorer.xaml.cs
@@ -220,7 +220,7 @@
             var appointment = new Appointment
             {
                 Subject = "Appointment",
-                StartTime = now.AddHours(-5),
+                StartTime = now,
                 Duration = TimeSpan.FromMinutes(30),
             };


Remove empty lines

Remove empty lines

--- test/Scrutor.Tests/OpenGenericDecorationTests.cs
+++ test/Scrutor.Tests/OpenGenericDecorationTests.cs
@@ -59,7 +59,6 @@

     public class MyQueryHandler : QueryHandler<MyQuery, MyResult> { }

-
     public class QueryHandler<TQuery, TResult> : IQueryHandler<TQuery, TResult> { }

     public class LoggingQueryHandler<TQuery, TResult> : DecoratorQueryHandler<TQuery, TResult>
@@ -67,14 +66,12 @@
         public LoggingQueryHandler(IQueryHandler<TQuery, TResult> inner) : base(inner) { }
     }

-
     public class TelemetryQueryHandler<TQuery, TResult> : DecoratorQueryHandler<TQuery, TResult>
     {
         public TelemetryQueryHandler(IQueryHandler<TQuery, TResult> inner) : base(inner) { }
     }

-
-    public class DecoratorQueryHandler<TQuery, TResult> :QueryHandler<TQuery, TResult>,  IDecoratorQueryHandler<TQuery, TResult>
+    public class DecoratorQueryHandler<TQuery, TResult> : QueryHandler<TQuery, TResult>, IDecoratorQueryHandler<TQuery, TResult>
     {
         public DecoratorQueryHandler(IQueryHandler<TQuery, TResult> inner)
         {


Archiving updates todo.txt file

Archiving updates todo.txt file

Fixed bug where archiving removed archived tasks from visible list, but
kept them in the file

--- TodotxtTouch.WindowsPhone/ViewModel/MainViewModel.cs
+++ TodotxtTouch.WindowsPhone/ViewModel/MainViewModel.cs
@@ -223,7 +223,7 @@
 		{
 		    _archiveFileService.LoadingStateChanged += ArchiveTasks;

-            _taskFileService.LoadingState = TaskLoadingState.Loading;
+            _taskFileService.LoadingState = TaskLoadingState.Syncing;

             _archiveFileService.Sync();
 		}
@@ -243,20 +243,21 @@
                 }

                 _archiveFileService.SaveTasks();
-
-                _archiveFileService.LoadingStateChanged += FinishArchiving;
+                _taskFileService.SaveTasks();
+
+                _archiveFileService.LoadingStateChanged += FinishSavingArchive;

                 _archiveFileService.Sync();
             }
         }

-        private void FinishArchiving(object obj, LoadingStateChangedEventArgs args)
+        private void FinishSavingArchive(object obj, LoadingStateChangedEventArgs args)
         {
             if (args.LoadingState == TaskLoadingState.Ready)
             {
-                _archiveFileService.LoadingStateChanged -= FinishArchiving;
-
-                _taskFileService.LoadingState = TaskLoadingState.Ready;
+                _archiveFileService.LoadingStateChanged -= FinishSavingArchive;
+
+                _taskFileService.Sync();
             }
         }


Acceptance tests.

Acceptance tests.

--- dotnet/Tests/Tests.cs
+++ dotnet/Tests/Tests.cs
@@ -42,30 +42,27 @@
             });

             // Get
-            var getList = _reachmail.Contacts.Lists.ByListId.Get(postList.Id);
-            getList.Id.ShouldEqual(postList.Id);
+            var getList = _reachmail.Contacts.Lists.ByListId.Get(postList.Id.Value);
+            getList.Id.ShouldEqual(postList.Id.Value);
             getList.Name.ShouldEqual(listName);
-            getList.Type.ShouldEqual(ListProperties.TypeOptions.Recipient);
+            getList.Type.ShouldEqual(ReachmailApi.Contacts.Lists.ByListId.Get.Response.List.TypeOptions.Recipient);
+
+            // Put
+            _reachmail.Contacts.Lists.ByListId.Put(postList.Id.Value,
+                new ReachmailApi.Contacts.Lists.ByListId.Put.Request.ListProperties { Name = "New" + listName });

             // Get many
             var queryLists = _reachmail.Contacts.Lists.Query.Post(new ListFilter { NewerThan = DateTime.Now.AddMinutes(20) });
             var queryList = queryLists.FirstOrDefault(x => x.Id == postList.Id);
             queryList.ShouldNotBeNull();
-            getList.Id.ShouldEqual(postList.Id);
-            getList.Name.ShouldEqual(listName);
-            getList.Type.ShouldEqual(ListProperties.TypeOptions.Recipient);
-
-            // Put
-            _reachmail.Contacts.Lists.ByListId.Put(postList.Id, new ListProperties { Name = "New" + listName });
-            getList = _reachmail.Contacts.Lists.ByListId.Get(postList.Id);
-            getList.Id.ShouldEqual(postList.Id);
+            getList.Id.ShouldEqual(postList.Id.Value);
             getList.Name.ShouldEqual("New" + listName);
-            getList.Type.ShouldEqual(ListProperties.TypeOptions.Recipient);
+            getList.Type.ShouldEqual(ReachmailApi.Contacts.Lists.ByListId.Get.Response.List.TypeOptions.Recipient);

             // Delete
-            _reachmail.Contacts.Lists.ByListId.Delete(listId.Id);
+            _reachmail.Contacts.Lists.ByListId.Delete(postList.Id.Value);
             _reachmail.Contacts.Lists.Query.Post(new ListFilter { NewerThan = DateTime.Now.AddMinutes(20) })
-                .Any(x => x.Id == listId.Id).ShouldBeFalse();
+                .Any(x => x.Id == postList.Id).ShouldBeFalse();
         }

         [Test]


Close #74

Close #74

--- TwitchPlaysAssembly/Src/Commands/HoldableCommands.cs
+++ TwitchPlaysAssembly/Src/Commands/HoldableCommands.cs
@@ -1,4 +1,5 @@
 using System.Collections;
+using UnityEngine;

 /// <summary>Contains commands for holdables (including the freeplay case and the missions binder).</summary>
 public static class HoldableCommands
@@ -16,6 +17,22 @@
 	[Command(@"(turn|turn round|turn around|rotate|flip|spin)")]
 	public static IEnumerator Flip(TwitchHoldable holdable) => holdable.Turn();

+	[Command("throw")]
+	public static IEnumerator Throw(TwitchHoldable holdable)
+	{
+		holdable.Holdable.Pause();
+		Rigidbody rigidbody = holdable.Holdable.GetComponent<Rigidbody>();
+		rigidbody.isKinematic = false;
+		rigidbody.useGravity = true;
+		rigidbody.velocity = Random.onUnitSphere * rigidbody.mass * 3;
+		rigidbody.angularVelocity = Random.onUnitSphere * rigidbody.mass * 3;
+		rigidbody.maxAngularVelocity = 100f;
+		yield return new WaitForSeconds(2);
+		rigidbody.isKinematic = true;
+		rigidbody.useGravity = false;
+		holdable.Holdable.Resume();
+	}
+
 	[Command(null)]
 	public static IEnumerator DefaultCommand(TwitchHoldable holdable, string user, bool isWhisper, string cmd)
 	{


Simplifie dlabels

Simplifie dlabels

--- HellBrick.Json/Utils/DebugViewWriter.cs
+++ HellBrick.Json/Utils/DebugViewWriter.cs
@@ -1237,7 +1237,7 @@

 		private void DumpLabel( LabelTarget target )
 		{
-			Out( String.Format( CultureInfo.CurrentCulture, ".LabelTarget {0}:", GetLabelTargetName( target ) ) );
+			Out( String.Format( CultureInfo.CurrentCulture, "{0}:", GetLabelTargetName( target ) ) );
 		}

 		private string GetLabelTargetName( LabelTarget target )


Push Api Controller Naming Clarity

Push Api Controller Naming Clarity

--- test/Microsoft.WindowsAzure.MobileServices.WindowsStore.Test/Functional/PushFunctional.Test.cs
+++ test/Microsoft.WindowsAzure.MobileServices.WindowsStore.Test/Functional/PushFunctional.Test.cs
@@ -119,7 +119,7 @@
             body.Add("type", "wns");
             body.Add("payload", payload);
             body.Add("token", "dummy");
-            body.Add("pushType", "toast");
+            body.Add("wnsType", "toast");
             body.Add("tag", "tag1");

             try


use the method...

use the method...

--- HiddenWatermark/ScaledWatermarkCache.cs
+++ HiddenWatermark/ScaledWatermarkCache.cs
@@ -46,13 +46,7 @@
         {
             if (_cache.Count > CacheSize)
             {
-                int min = 999;
-                foreach (var pair in _cache)
-                {
-                    if (_count[pair.Key] < min)
-                        min = _count[pair.Key];
-                }
-
+                int min = SmallestCacheCount();
                 foreach (var pair in _cache)
                 {
                     if (_count[pair.Key] == min)


Fixed a broken unit test

Fixed a broken unit test

--- UnitTests/Cryptography/AuthenticationResultsTests.cs
+++ UnitTests/Cryptography/AuthenticationResultsTests.cs
@@ -171,7 +171,7 @@

 			authres.Results.Add (new AuthenticationMethodResult ("really-really-really-long-method-name", "really-really-really-long-value") {
 				ResultComment = "this is a really really long result comment",
-				Action = "this is a really really really long reason",
+				Reason = "this is a really really really long reason",
 				Version = 214748367
 			});
 			authres.Results[0].Properties.Add (new AuthenticationMethodProperty ("this-is-a-really-really-long-ptype", "this-is-a-really-really-long-property", "this-is-a-really-really-long-value"));


remove unused variable

remove unused variable

--- client/BlueMonkey/BlueMonkey/ViewModels/LoginPageViewModel.cs
+++ client/BlueMonkey/BlueMonkey/ViewModels/LoginPageViewModel.cs
@@ -49,7 +49,7 @@
                 }
                 await _navigationService.NavigateAsync("/NavigationPage/MainPage");
             }
-            catch (Exception ex)
+            catch (Exception)
             {
                 await _pageDialogService.DisplayAlertAsync(
                     "Information",


All output messages are on their own line now

--- Devkoes.VSJenkinsManager/Devkoes.JenkinsManager.VSPackage/ExposedServices/OutputWindowLogger.cs
+++ Devkoes.VSJenkinsManager/Devkoes.JenkinsManager.VSPackage/ExposedServices/OutputWindowLogger.cs
@@ -22,7 +22,7 @@

                 outWindow.GetPane(ref outputWindowGuid, out _outputWindow);

-                _outputWindow.OutputString("Jenkins Manager loaded");
+                LogOutput("Jenkins Manager loaded");
             }
             catch (Exception)
             {
@@ -35,18 +35,14 @@
         {
             try
             {
-                _outputWindow.OutputString(message);
+                _outputWindow.OutputString(string.Concat(message, Environment.NewLine));
             }
             catch { }
         }

         public void LogOutput(string format, params object[] args)
         {
-            try
-            {
-                _outputWindow.OutputString(string.Format(format, args));
-            }
-            catch { }
+            LogOutput(string.Format(format, args));
         }

         public void LogOutput(Exception ex)
@@ -56,11 +52,7 @@
                 return;
             }

-            try
-            {
-                _outputWindow.OutputString(ex.ToString());
-            }
-            catch { }
+            LogOutput(ex.ToString());
         }

         public void LogOutput(string message, Exception ex)


Changed lookupfields handler to always run during provisioning

--- OfficeDevPnP.Core/OfficeDevPnP.Core/Framework/Provisioning/ObjectHandlers/ObjectLookupFields.cs
+++ OfficeDevPnP.Core/OfficeDevPnP.Core/Framework/Provisioning/ObjectHandlers/ObjectLookupFields.cs
@@ -139,7 +139,7 @@
         {
             if (!_willProvision.HasValue)
             {
-                _willProvision = template.SiteFields.Any();
+                _willProvision = true;
             }
             return _willProvision.Value;
         }