Added some extra format options when writing the feed

--- src/Skybrud.Umbraco.RssUtils/RssFeed.cs
+++ src/Skybrud.Umbraco.RssUtils/RssFeed.cs
@@ -193,10 +193,14 @@
             );

         }
-
+
         public void Write() {
+            Write(SaveOptions.DisableFormatting);
+        }
+
+        public void Write(SaveOptions options) {
             HttpContext.Current.Response.ContentType = "application/rss+xml";
-            ToXDocument().Save(HttpContext.Current.Response.OutputStream);
+            ToXDocument().Save(HttpContext.Current.Response.OutputStream, options);
             HttpContext.Current.Response.End();
         }


Fix comment

Fix comment

--- src/SourceCode.Clay/StringExtensions.cs
+++ src/SourceCode.Clay/StringExtensions.cs
@@ -42,7 +42,7 @@
         /// <summary>
         /// Truncates a string, inserting an ellipsis if necessary, returning a value with the specified total width.
         /// Tolerates <paramref name="totalWidth"/> values that are too large or too small (or negative).
-        /// It the value is already smaller then <paramref name="totalWidth"/>, the original value is returned.
+        /// If the value is already smaller then <paramref name="totalWidth"/>, the original value is returned.
         /// Otherwise the value is truncated to the specified <paramref name="totalWidth"/> and the
         /// final 3 characters are replaced with "...".
         /// </summary>


WebApi: Fix test threading.

WebApi: Fix test threading.

--- tests/Microsoft.AspNet.WebApi.Owin.Tests/AdaptersTests.cs
+++ tests/Microsoft.AspNet.WebApi.Owin.Tests/AdaptersTests.cs
@@ -101,7 +101,7 @@
         public void SendResponseMessageNoContent()
         {
             IDictionary<string, object> call = NewEnvironment(x => { }, x => { });
-            OwinHttpMessageUtilities.SendResponseMessage(call, new HttpResponseMessage(), CancellationToken.None);
+            OwinHttpMessageUtilities.SendResponseMessage(call, new HttpResponseMessage(), CancellationToken.None).Wait();
             call.Get<int>("owin.ResponseStatusCode").ShouldBe(200);
             call.Get<string>("owin.ResponseReasonPhrase").ShouldBe("OK");
         }
@@ -114,7 +114,7 @@
                 new HttpResponseMessage()
                 {
                     Content = new StringContent("Hello World")
-                }, CancellationToken.None);
+                }, CancellationToken.None).Wait();
             call.Get<int>("owin.ResponseStatusCode").ShouldBe(200);
             call.Get<string>("owin.ResponseReasonPhrase").ShouldBe("OK");
             var responseHeaders = call.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");


Use MarkupCode in CodeActionV2Facts

Use MarkupCode in CodeActionV2Facts

--- tests/OmniSharp.Roslyn.CSharp.Tests/CodeActionsV2Facts.cs
+++ tests/OmniSharp.Roslyn.CSharp.Tests/CodeActionsV2Facts.cs
@@ -4,6 +4,7 @@
 using System.Linq;
 using System.Reflection;
 using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.Text;
 using OmniSharp.Models.V2;
 using OmniSharp.Roslyn.CSharp.Services;
 using OmniSharp.Roslyn.CSharp.Services.CodeActions;
@@ -85,7 +86,7 @@
                     {
                         public void Whatever()
                         {
-                            Gu$id.NewGuid();
+                            Gu[||]id.NewGuid();
                         }
                     }";

@@ -101,7 +102,7 @@
                 using MyNamespace4;
                 using MyNamespace2;
                 using System;
-                u$sing MyNamespace1;
+                u[||]sing MyNamespace1;

                 public class c {public c() {Guid.NewGuid();}}";

@@ -122,7 +123,7 @@
               {
                   public void Whatever()
                   {
-                      $Console.Write(""should be using System;"");$
+                      [|Console.Write(""should be using System;"");|]
                   }
               }";

@@ -138,7 +139,7 @@
                   {
                       public void Whatever()
                       {
-                          $Console.Write(""should be using System;"");$
+                          [|Console.Write(""should be using System;"");|]
                       }
                   }";

@@ -169,7 +170,7 @@
                 {
                     public void Whatever()
                     {
-                        MyNew$Class.DoSomething();
+                        MyNew[||]Class.DoSomething();
                     }
                 }";

@@ -236,9 +237,22 @@
             return codeActions.Select(a => a.Name);
         }

-        private async Task<IEnumerable<OmniSharpCodeAction>> FindRefactoringsAsync(string source)
-        {
-            var request = CreateGetCodeActionsRequest(source);
+        private async Task<IEnumerable<OmniSharpCodeAction>> FindRefactoringsAsync(string input)
+        {
+            var markup = MarkupCode.Parse(input);
+            var span = markup.GetSpans().Single();
+            var text = SourceText.From(markup.Code);
+            var range = GetRange(text, span);
+
+            var request = new GetCodeActionsRequest
+            {
+                Line = range.Start.Line,
+                Column = range.Start.Column,
+                FileName = BufferPath,
+                Buffer = markup.Code,
+                Selection = range.Start.Equals(range.End) ? null : range
+            };
+
             var workspace = await GetOmniSharpWorkspace(request);
             var codeActions = CreateCodeActionProviders();

@@ -263,48 +277,38 @@
             return response;
         }

-        private GetCodeActionsRequest CreateGetCodeActionsRequest(string source)
-        {
-            var range = TestHelpers.GetRangeFromDollars(source);
-
-            return new GetCodeActionsRequest
+        private RunCodeActionRequest CreateRunCodeActionRequest(string input, string identifier, bool wantChanges)
+        {
+            var markup = MarkupCode.Parse(input);
+            var span = markup.GetSpans().Single();
+            var text = SourceText.From(markup.Code);
+            var range = GetRange(text, span);
+
+            return new RunCodeActionRequest
             {
                 Line = range.Start.Line,
                 Column = range.Start.Column,
+                Selection = range.Start.Equals(range.End) ? null : range,
                 FileName = BufferPath,
-                Buffer = source.Replace("$", ""),
-                Selection = GetSelection(range)
-            };
-        }
-
-        private RunCodeActionRequest CreateRunCodeActionRequest(string source, string identifier, bool wantChanges)
-        {
-            var range = TestHelpers.GetRangeFromDollars(source);
-            var selection = GetSelection(range);
-
-            return new RunCodeActionRequest
-            {
-                Line = range.Start.Line,
-                Column = range.Start.Column,
-                Selection = selection,
-                FileName = BufferPath,
-                Buffer = source.Replace("$", ""),
+                Buffer = markup.Code,
                 Identifier = identifier,
                 WantsTextChanges = wantChanges
             };
         }

-        private static Range GetSelection(TestHelpers.Range range)
-        {
-            Range selection = null;
-            if (!range.IsEmpty)
-            {
-                var start = new Point { Line = range.Start.Line, Column = range.Start.Column };
-                var end = new Point { Line = range.End.Line, Column = range.End.Column };
-                selection = new Range { Start = start, End = end };
-            }
-
-            return selection;
+        private static Range GetRange(SourceText text, TextSpan span)
+        {
+            var startLine = text.Lines.GetLineFromPosition(span.Start);
+            var startColumn = span.Start - startLine.Start;
+
+            var endLine = text.Lines.GetLineFromPosition(span.End);
+            var endColumn = span.End - endLine.Start;
+
+            return new Range
+            {
+                Start = new Point { Line = startLine.LineNumber, Column = startColumn },
+                End = new Point { Line = endLine.LineNumber, Column = endColumn }
+            };
         }

         private IEnumerable<ICodeActionProvider> CreateCodeActionProviders()


Fix MT940

Fix MT940

--- src/libfintx/MT940/MT940.cs
+++ src/libfintx/MT940/MT940.cs
@@ -163,7 +163,7 @@
                 swiftData = swiftData.Substring(6);

                 // Posting date (MMDD)
-                if (Regex.IsMatch(swiftData, @"\d{4}"))
+                if (Regex.IsMatch(swiftData, @"^\d{4}"))
                 {
                     int year = SWIFTTransaction.valueDate.Year;
                     int month = Convert.ToInt32(swiftData.Substring(0, 2));
@@ -186,7 +186,7 @@
                 }

                 // Amount - some characters followed by an 'N'
-                if (Regex.IsMatch(swiftData, @".+N"))
+                if (Regex.IsMatch(swiftData, @"^.+N"))
                 {
                     // Debit or credit, or storno debit or credit
                     int debitCreditIndicator = 0;


Cleaned up DOF effect.

Cleaned up DOF effect.

--- sys/postFx/dof.cs
+++ sys/postFx/dof.cs
@@ -26,6 +26,9 @@
  The DOFFx API
 ================================================================================

+Note that DOFFx requires ServerConnection to exist. It operates on
+ServerConnection.getCameraObject().
+
 DOFFx::setFocalDist( %dist )

 @summary
@@ -400,61 +403,51 @@
    targetScale = "0.25 0.25";

    isEnabled = false;
-};
-
-singleton PostEffect( DOFBlurY )
-{
-   shader = PFX_DOFBlurYShader;
-   stateBlock = PFX_DOFBlurStateBlock;
-   texture[0] = "#shrunk";
-   target = "$outTex";
-};
-
-DOFFx.add( DOFBlurY );
-
-singleton PostEffect( DOFBlurX )
-{
-   shader = PFX_DOFBlurXShader;
-   stateBlock = PFX_DOFBlurStateBlock;
-   texture[0] = "$inTex";
-   target = "#largeBlur";
-};
-
-DOFFx.add( DOFBlurX );
-
-singleton PostEffect( DOFCalcCoC )
-{
-   shader = PFX_DOFCalcCoCShader;
-   stateBlock = PFX_DOFCalcCoCStateBlock;
-   texture[0] = "#shrunk";
-   texture[1] = "#largeBlur";
-   target = "$outTex";
-};
-
-DOFFx.add( DOFCalcCoc );
-
-singleton PostEffect( DOFSmallBlur )
-{
-   shader = PFX_DOFSmallBlurShader;
-   stateBlock = PFX_DefaultDOFStateBlock;
-   texture[0] = "$inTex";
-   target = "$outTex";
-};
-
-DOFFx.add( DOFSmallBlur );
-
-singleton PostEffect( DOFFinalPFX )
-{
-   shader = PFX_DOFFinalShader;
-   stateBlock = PFX_DOFFinalStateBlock;
-   texture[0] = "$backBuffer";
-   texture[1] = "$inTex";
-   texture[2] = "#largeBlur";
-   texture[3] = "#prepass";
-   target = "$backBuffer";
-};
-
-DOFFx.add( DOFFinalPFX );
+
+   singleton PostEffect()
+   {
+      shader = PFX_DOFBlurYShader;
+      stateBlock = PFX_DOFBlurStateBlock;
+      texture[0] = "#shrunk";
+      target = "$outTex";
+   };
+
+   singleton PostEffect()
+   {
+      shader = PFX_DOFBlurXShader;
+      stateBlock = PFX_DOFBlurStateBlock;
+      texture[0] = "$inTex";
+      target = "#largeBlur";
+   };
+
+   singleton PostEffect()
+   {
+      shader = PFX_DOFCalcCoCShader;
+      stateBlock = PFX_DOFCalcCoCStateBlock;
+      texture[0] = "#shrunk";
+      texture[1] = "#largeBlur";
+      target = "$outTex";
+   };
+
+   singleton PostEffect()
+   {
+      shader = PFX_DOFSmallBlurShader;
+      stateBlock = PFX_DefaultDOFStateBlock;
+      texture[0] = "$inTex";
+      target = "$outTex";
+   };
+
+   singleton PostEffect()
+   {
+      shader = PFX_DOFFinalShader;
+      stateBlock = PFX_DOFFinalStateBlock;
+      texture[0] = "$backBuffer";
+      texture[1] = "$inTex";
+      texture[2] = "#largeBlur";
+      texture[3] = "#prepass";
+      target = "$backBuffer";
+   };
+};

 //-----------------------------------------------------------------------------


resolves #76

resolves #76

--- slimCat/ViewModels/Channels/GeneralChannelViewModel.cs
+++ slimCat/ViewModels/Channels/GeneralChannelViewModel.cs
@@ -68,6 +68,10 @@

         private bool autoPostAds;

+        private int autoPostCount;
+
+        private DateTimeOffset autoTimeLeft;
+
         private bool hasNewAds;

         private bool hasNewMessages;
@@ -88,11 +92,7 @@

         private DateTimeOffset timeLeftAd;

-        private DateTimeOffset autoTimeLeft;
-
         private Timer updateTimer = new Timer(1000);
-
-        private int autoPostCount;

         #endregion

@@ -194,7 +194,6 @@
                 PropertyChanged += OnPropertyChanged;

                 Events.GetEvent<NewUpdateEvent>().Subscribe(UpdateChat);
-
             }
             catch (Exception ex)
             {
@@ -218,9 +217,7 @@
                 // set the interval time to however many minutes in miliseconds
                 // plus two seconds in miliseconds
                 if (!isInCoolDownAd)
-                {
                     adFloodTimer.Interval = Model.Settings.AutopostTime*60*1000 + 2000;
-                }

                 OnPropertyChanged("AutoPost");
                 OnPropertyChanged("CanShowAutoTimeLeft");
@@ -511,7 +508,15 @@
                 return;
             }

-            Events.SendUserCommand(CommandDefinitions.ClientSendChannelAd, new[] {messageToSend}, Model.Id);
+            var last = Model.Ads.Last();
+            if (last != null)
+            {
+                if (!last.Poster.NameEquals(ChatModel.CurrentCharacter.Name))
+                    Events.SendUserCommand(CommandDefinitions.ClientSendChannelAd, new[] {messageToSend}, Model.Id);
+            }
+            else
+                Events.SendUserCommand(CommandDefinitions.ClientSendChannelAd, new[] {messageToSend}, Model.Id);
+
             adFloodTimer.Interval = Model.Settings.AutopostTime*60*1000 + 2000;
             timeLeftAd = DateTimeOffset.Now.AddMilliseconds(adFloodTimer.Interval);

@@ -525,7 +530,7 @@

             if (autoPostCount < MaxAutoPosts) return;

-            autoTimeLeft = DateTime.Now.AddMilliseconds(adFloodTimer.Interval * (MaxAutoPosts - autoPostCount));
+            autoTimeLeft = DateTime.Now.AddMilliseconds(adFloodTimer.Interval*(MaxAutoPosts - autoPostCount));
             AutoPost = false;
             OnPropertyChanged("CanShowAutoTimeLeft");
             autoPostCount = 0;
@@ -657,7 +662,7 @@
             else
             {
                 timeLeftAd = DateTime.Now.AddMilliseconds(adFloodTimer.Interval);
-                autoTimeLeft = DateTime.Now.AddMilliseconds(adFloodTimer.Interval * MaxAutoPosts);
+                autoTimeLeft = DateTime.Now.AddMilliseconds(adFloodTimer.Interval*MaxAutoPosts);

                 isInCoolDownAd = true;
                 OnPropertyChanged("CanPost");


add deleting configs backend, fix json content too long

--- sniper/sniper/Controllers/SearchConfigApiController.cs
+++ sniper/sniper/Controllers/SearchConfigApiController.cs
@@ -1,6 +1,8 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
 using System.Linq;
 using System.Web.Mvc;
+using System.Web.Script.Serialization;
 using Raven.Client;
 using sniper.Common.Mapping;
 using sniper.Models;
@@ -41,16 +43,34 @@
             return Json(new {Message = "Success"});
         }

-        public JsonResult List()
+        public ContentResult List()
         {
             var searchConfigs = RavenSession.Query<SearchConfig>().ToList();
+            var serializer = new JavaScriptSerializer {MaxJsonLength = Int32.MaxValue};
+            var result = new ContentResult
+            {
+                Content = serializer.Serialize(searchConfigs),
+                ContentType = "application/json"
+            };

-            return Json(searchConfigs);
+            return result;
         }

         public void SaveRunData(SearchData data)
         {
             RavenSession.Store(data);
         }
+
+        public void DeleteConfig(int configId)
+        {
+            var datas = RavenSession.Query<SearchData>().Where(sd => sd.SearchConfigId == configId).ToList();
+            foreach (var searchData in datas)
+            {
+                RavenSession.Delete(searchData);
+            }
+
+            var config = RavenSession.Load<SearchConfig>(configId);
+            RavenSession.Delete(config);
+        }
     }
 }


Add photo url to profile claims

Add photo url to profile claims

--- src/auth-web/Services/SarUserService.cs
+++ src/auth-web/Services/SarUserService.cs
@@ -278,6 +278,11 @@
           {
             claims.Add(new Claim(Constants.ClaimTypes.Profile, string.Format(profileTemplate, member.Id)));
           }
+
+          if (!string.IsNullOrWhiteSpace(member.PhotoUrl))
+          {
+            claims.Add(new Claim("photo", member.PhotoUrl));
+          }
         }

         var roles = _roles.RolesForAccount(account.Id);
@@ -292,7 +297,7 @@
         claims.Add(new Claim(Constants.ClaimTypes.GivenName, account.FirstName));
         claims.Add(new Claim(Constants.ClaimTypes.FamilyName, account.LastName));
         claims.Add(new Claim(Constants.ClaimTypes.Name, account.FirstName + " " + account.LastName));
-
+

         context.IssuedClaims = context.AllClaimsRequested ? claims : claims.Where(f => context.RequestedClaimTypes.Contains(f.Type));
       }


Minor refactoring.

Minor refactoring.

--- src/Abp.Web.Api/WebApi/Controllers/AbpApiController.cs
+++ src/Abp.Web.Api/WebApi/Controllers/AbpApiController.cs
@@ -1,10 +1,7 @@
 using System;
 using System.Globalization;
-using System.Net.Http;
-using System.Threading;
 using System.Threading.Tasks;
 using System.Web.Http;
-using System.Web.Http.Controllers;
 using Abp.Authorization;
 using Abp.Configuration;
 using Abp.Localization;
@@ -111,7 +108,7 @@
         /// <param name="name">Key name</param>
         /// <param name="args">Format arguments</param>
         /// <returns>Localized string</returns>
-        public string L(string name, params object[] args)
+        protected string L(string name, params object[] args)
         {
             return LocalizationSource.GetString(name, args);
         }
@@ -134,7 +131,7 @@
         /// <param name="culture">culture information</param>
         /// <param name="args">Format arguments</param>
         /// <returns>Localized string</returns>
-        public string L(string name, CultureInfo culture, params object[] args)
+        protected string L(string name, CultureInfo culture, params object[] args)
         {
             return LocalizationSource.GetString(name, culture, args);
         }


Fixed issue with websocket exceptions being printed as an unhandled exception.

--- src/Commands/Advobot.Logging/Service/LoggingService.cs
+++ src/Commands/Advobot.Logging/Service/LoggingService.cs
@@ -62,20 +62,18 @@
 			ConsoleUtils.WriteLine(message.Message, name: message.Source);
 		}

-		switch (message.Exception)
+		if (message.Exception is GatewayReconnectException)
 		{
-			case GatewayReconnectException _:
-				ConsoleUtils.WriteLine("Gateway reconnection requested.", ConsoleColor.Yellow, message.Source);
-				break;
-
-			case WebSocketClosedException _:
-			case WebSocketException _:
-				ConsoleUtils.WriteLine(message.Exception.Message, ConsoleColor.Yellow, message.Source);
-				break;
-
-			default:
-				message.Exception?.Write(message.Source);
-				break;
+			ConsoleUtils.WriteLine("Gateway reconnection requested.", ConsoleColor.Yellow, message.Source);
+		}
+		else if (message.Exception.InnerException is Exception ie
+			&& ie is WebSocketClosedException or WebSocketException)
+		{
+			ConsoleUtils.WriteLine(ie.Message, ConsoleColor.Yellow, message.Source);
+		}
+		else
+		{
+			message.Exception?.Write(message.Source);
 		}

 		return Task.CompletedTask;


Reduce calls to AddError.

Reduce calls to AddError.

--- src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
+++ src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
@@ -4983,8 +4983,8 @@
                     ExpressionSyntax value;
                     if (this.CurrentToken.Kind == SyntaxKind.CommaToken || this.CurrentToken.Kind == SyntaxKind.CloseBraceToken)
                     {
-                        value = this.CreateMissingIdentifierName(); //an identifier is a valid expression
-                        value = this.AddErrorToFirstToken(value, ErrorCode.ERR_ConstantExpected);
+                        //an identifier is a valid expression
+                        value = this.ParseIdentifierName(ErrorCode.ERR_ConstantExpected);
                     }
                     else
                     {
@@ -5068,7 +5068,7 @@
                 !(this.IsInQuery && IsTokenQueryContextualKeyword(token));
         }

-        private IdentifierNameSyntax ParseIdentifierName()
+        private IdentifierNameSyntax ParseIdentifierName(ErrorCode code = ErrorCode.ERR_IdentifierExpected)
         {
             if (this.IsIncrementalAndFactoryContextMatches && this.CurrentNodeKind == SyntaxKind.IdentifierName)
             {
@@ -5078,11 +5078,11 @@
                 }
             }

-            var tk = ParseIdentifierToken();
+            var tk = ParseIdentifierToken(code);
             return SyntaxFactory.IdentifierName(tk);
         }

-        private SyntaxToken ParseIdentifierToken()
+        private SyntaxToken ParseIdentifierToken(ErrorCode code = ErrorCode.ERR_IdentifierExpected)
         {
             var ctk = this.CurrentToken.Kind;
             if (ctk == SyntaxKind.IdentifierToken)
@@ -5112,7 +5112,7 @@
             else
             {
                 var name = CreateMissingIdentifierToken();
-                name = this.AddError(name, ErrorCode.ERR_IdentifierExpected);
+                name = this.AddError(name, code);
                 return name;
             }
         }
@@ -7993,8 +7993,7 @@

                         if (this.CurrentToken.Kind == SyntaxKind.ColonToken)
                         {
-                            expression = this.CreateMissingIdentifierName();
-                            expression = this.AddError(expression, ErrorCode.ERR_ConstantExpected);
+                            expression = ParseIdentifierName(ErrorCode.ERR_ConstantExpected);
                             colon = this.EatToken(SyntaxKind.ColonToken);
                             label = _syntaxFactory.CaseSwitchLabel(specifier, expression, colon);
                         }
@@ -9651,11 +9650,11 @@

             if (isIndexer && (this.CurrentToken.Kind == SyntaxKind.CommaToken || this.CurrentToken.Kind == SyntaxKind.CloseBracketToken))
             {
-                expression = this.AddError(this.CreateMissingIdentifierName(), ErrorCode.ERR_ValueExpected);
+                expression = this.ParseIdentifierName(ErrorCode.ERR_ValueExpected);
             }
             else if (this.CurrentToken.Kind == SyntaxKind.CommaToken)
             {
-                expression = this.AddError(this.CreateMissingIdentifierName(), ErrorCode.ERR_MissingArgument);
+                expression = this.ParseIdentifierName(ErrorCode.ERR_MissingArgument);
             }
             else
             {


DateButton: Update size calculation to use GetPreferredHeight

--- src/Core/Banshee.Widgets/Banshee.Widgets/DateButton.cs
+++ src/Core/Banshee.Widgets/Banshee.Widgets/DateButton.cs
@@ -81,23 +81,24 @@
 			calAlignment.Add(cal);

 			box.PackStart(calAlignment, false, false, 0);
-
-			Requisition req = SizeRequest();
+
+			int minimum_height, natural_height;
+			GetPreferredHeight (out minimum_height, out natural_height);
 			int x = 0, y = 0;
-			GdkWindow.GetOrigin(out x, out y);
-			popup.Move(x + Allocation.X, y + Allocation.Y + req.Height + 3);
+			Window.GetOrigin(out x, out y);
+			popup.Move(x + Allocation.X, y + Allocation.Y + natural_height + 3);
 			popup.Show();
 			popup.GrabFocus();

 			Grab.Add(popup);

-			Gdk.GrabStatus grabbed = Gdk.Pointer.Grab(popup.GdkWindow, true,
+			Gdk.GrabStatus grabbed = Gdk.Pointer.Grab(popup.Window, true,
 				Gdk.EventMask.ButtonPressMask
 				| Gdk.EventMask.ButtonReleaseMask
 				| Gdk.EventMask.PointerMotionMask, null, null, CURRENT_TIME);

 			if(grabbed == Gdk.GrabStatus.Success) {
-				grabbed = Gdk.Keyboard.Grab(popup.GdkWindow,
+				grabbed = Gdk.Keyboard.Grab(popup.Window,
 					true, CURRENT_TIME);

 				if(grabbed != Gdk.GrabStatus.Success) {


CBL-3228 Scopes and Collections without Document unit tests (#1387)

* CBL-3228 Scopes and Collections without Document unit tests

--- src/Couchbase.Lite.Tests.Shared/ScopeCollectionTest.cs
+++ src/Couchbase.Lite.Tests.Shared/ScopeCollectionTest.cs
@@ -89,5 +89,278 @@
         }

+        [Fact]
+        public void TestCreateAndGetCollectionsInDefaultScope()
+        {
+            var colA = Db.CreateCollection("colA");
+            var colB = Db.CreateCollection("colB");
+            var colC = Db.CreateCollection("colC", Database._defaultScopeName);
+            //the created collection objects have the correct name and scope.
+            colA.Name.Should().Be("colA", "object colA has the correct name colA");
+            colA.Scope.Name.Should().Be(Database._defaultScopeName, $"objects colA has the correct scope {Database._defaultScopeName}");
+            colB.Name.Should().Be("colB", "object colB has the correct name colB");
+            colB.Scope.Name.Should().Be(Database._defaultScopeName, $"objects colB has the correct scope {Database._defaultScopeName}");
+            colC.Name.Should().Be("colC", "object colC has the correct name colC");
+            colC.Scope.Name.Should().Be(Database._defaultScopeName, $"objects colC has the correct scope {Database._defaultScopeName}");
+            //the created collections exist when calling database.GetCollection(name: String)
+            Db.GetCollection("colA").Should().Be(colA);
+            Db.GetCollection("colB").Should().Be(colB);
+            Db.GetCollection("colC").Should().Be(colC);
+            //the created collections are in the list when calling database.GetCollections().
+            var colls = Db.GetCollections();
+            colls.Contains(colA).Should().BeTrue();
+            colls.Contains(colB).Should().BeTrue();
+            colls.Contains(colC).Should().BeTrue();
+        }
+
+        [Fact]
+        public void TestCreateAndGetCollectionsInNamedScope()
+        {
+            Db.GetScope("scopeA").Should().BeNull("Because there is no scope scopeA in Database");
+            Db.CreateCollection("colA", "scopeA");
+            var scopeA = Db.GetScope("scopeA");
+            scopeA.Should().NotBeNull("Because scope scopeA was created in Database two lines ago.");
+            scopeA.Name.Should().Be("scopeA", "the created collection has the correct scope scopeA");
+            var colA = scopeA.GetCollection("colA");
+            colA.Name.Should().Be("colA", "the created collections have the correct name colA");
+            var scopes = Db.GetScopes();
+            scopes.Contains(scopeA).Should().BeTrue("the created collection’s scope is in the list when calling Database.GetScopes()");
+            var collections = Db.GetCollections("scopeA");
+            collections.Contains(colA).Should().BeTrue("the created collection is in the list from Database.GetCollections with scopeA");
+        }
+
+        [Fact]
+        public void TestGetNonExistingCollection()
+        {
+            var col = Db.GetCollection("colA", "scoppeA");
+            col.Should().BeNull("No collection colA existed");
+        }
+
+        [Fact]
+        public void TestGetCollectionsFromScope()
+        {
+            var colA = Db.CreateCollection("colA", "scopeA");
+            var colB = Db.CreateCollection("colB", "scopeA");
+            var scope = Db.GetScope("scopeA");
+            scope.GetCollection("colA").Should().Be(colA, "Because collection colA is in scopeA");
+            scope.GetCollection("colB").Should().Be(colB, "Because collection colB is in scopeA");
+            //Get all of the created collections by using scope.getCollections() API. Ensure that the collections are returned correctly.
+            var cols = Db.GetCollections("scopeA");
+            cols.Count.Should().Be(2, "total 2 collection is added in the Database");
+            // Check if collections order is required
+            cols.Contains(colA).Should().BeTrue();
+            cols.Contains(colB).Should().BeTrue();
+        }
+
+        [Fact]
+        public void TestDeleteAllCollectionsInScope()
+        {
+            var colA = Db.CreateCollection("colA", "scopeA");
+            var colB = Db.CreateCollection("colB", "scopeA");
+            var scopeA = Db.GetScope("scopeA");
+            var collectionsInScopeA = scopeA.GetCollections();
+            collectionsInScopeA.Count.Should().Be(2, "Because 2 collections were just added in the Database.");
+            collectionsInScopeA.Contains(colA).Should().BeTrue("Because collecton colA is in scopeA");
+            collectionsInScopeA.Contains(colB).Should().BeTrue("Because collecton colB is in scopeA");
+            Db.DeleteCollection("colA", "scopeA");
+            scopeA.GetCollections().Count.Should().Be(1, "Collections count should be 1 because colA is deleted from scopeA");
+            Db.DeleteCollection("colB", "scopeA");
+            Db.GetScope("scopeA").Should().BeNull();
+            Db.GetCollection("colA", "scopeA").Should().BeNull("because colA is deleted from scopeA");
+            Db.GetCollection("colB", "scopeA").Should().BeNull("because colB is deleted from scopeA");
+        }
+
+        [Fact]
+        public void TestCollectionNameWithValidChars()
+        {
+            // None default Collection and Scope Names are allowed to contain the following characters
+            // A - Z, a - z, 0 - 9, and the symbols _, -, and % and to start with A-Z, a-z, 0-9, and -
+            var str = "_%";
+            for (char letter = 'A'; letter <= 'Z'; letter++) {
+                Db.CreateCollection(letter + str).Should().NotBeNull($"Valid collection name '{letter + str}'.");
+            }
+
+            // TODO : wait for CBL-3195 fix
+            //for (char letter = 'a'; letter <= 'z'; letter++) {
+            //    Db.CreateCollection(letter + str).Should().NotBeNull($"Valid collection name '{letter + str}'.");
+            //}
+
+            for (char letter = '0'; letter <= '9'; letter++) {
+                Db.CreateCollection(letter + str).Should().NotBeNull($"Valid collection name '{letter + str}'.");
+            }
+
+            Db.CreateCollection("-" + str).Should().NotBeNull($"Valid collection name '{"-" + str}'.");
+        }
+
+        [Fact]
+        public void TestCollectionNameStartWithIllegalChars()
+        {
+            // None default Collection and Scope Names start with _ and % are prohibited
+            Action badAction = (() => Db.CreateCollection("_"));
+            badAction.Should().Throw<CouchbaseLiteException>("Invalid collection name '_' in scope '_default'.");
+            badAction = (() => Db.CreateCollection("%"));
+            badAction.Should().Throw<CouchbaseLiteException>("Invalid collection name '%' in scope '_default'.");
+        }
+
+        [Fact]
+        public void TestCollectionNameContainingIllegalChars()
+        {
+            var str = "ab";
+            /* Create collections with the collection name containing the following characters
+               !, @, #, $, ^, &, *, (, ), +, -, ., <, >, ?, [, ], {, }, =, “, ‘, |, \, /,`,~ are prohibited. */
+            for (char letter = '!'; letter <= '/'; letter++) {
+                if (letter == '%')
+                    return;
+                Action badAction = (() => Db.CreateCollection(str + letter));
+                badAction.Should().Throw<CouchbaseLiteException>($"Invalid collection name '{str + letter}' in scope '_default'.");
+            }
+
+            for (char letter = '<'; letter <= '@'; letter++) {
+                Action badAction = (() => Db.CreateCollection(str + letter));
+                badAction.Should().Throw<CouchbaseLiteException>($"Invalid collection name '{str + letter}' in scope '_default'.");
+            }
+
+            for (char letter = '['; letter <= '`'; letter++) {
+                Action badAction = (() => Db.CreateCollection(str + letter));
+                badAction.Should().Throw<CouchbaseLiteException>($"Invalid collection name '{str + letter}' in scope '_default'.");
+            }
+
+            for (char letter = '{'; letter <= '~'; letter++) {
+                Action badAction = (() => Db.CreateCollection(str + letter));
+                badAction.Should().Throw<CouchbaseLiteException>($"Invalid collection name '{str + letter}' in scope '_default'.");
+            }
+        }
+
+        [Fact]
+        public void TestCollectionNameLength()
+        {
+            /* Collection name should contain valid char with length from 1 to 251 */
+            var collName = "";
+            for (int i = 0; i < 251; i++) {
+                collName += 'c';
+                collName.Length.Should().Be(i + 1);
+                Db.CreateCollection(collName).Should().NotBeNull($"Valid collection '{collName}' length {collName.Length}.");
+            }
+
+            var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_%-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";
+            str.Length.Should().Be(251);
+            Db.CreateCollection(str).Should().NotBeNull($"because the collection name can be length at {str.Length}");
+
+            str += "e";
+            str.Length.Should().Be(252);
+            Action badAction = (() => Db.CreateCollection(str));
+            badAction.Should().Throw<CouchbaseLiteException>($"Invalid collection name '{str}' in scope because the collection name length {str.Length} is over naming length limit.");
+        }
+
+        [Fact] // I think this test case is a dup of TestCollectionNameWithValidChars?
+        public void TestCollectionNameCaseSensitive()
+        {
+            Db.CreateCollection("COLLECTION1").Should().NotBeNull();
+            // TODO : wait for CBL-3195 fix
+            //Db.CreateCollection("collection1").Should().NotBeNull("Should be able to be created because collection name is case sensitive.");
+            //This will already return non-null, it will just be the same as COLLECTION1. The test should ensure they are different from each other (e.g. independent documents)
+        }
+
+        [Fact]
+        public void TestScopeNameWithValidChars()
+        {
+            // None default Collection and Scope Names are allowed to contain the following characters
+            // A - Z, a - z, 0 - 9, and the symbols _, -, and % and to start with A-Z, a-z, 0-9, and -
+            var str = "_%";
+            for (char letter = 'A'; letter <= 'Z'; letter++) {
+                Db.CreateCollection("abc", letter + str).Should().NotBeNull($"Valid scope name '{letter + str}'.");
+            }
+
+            // TODO : wait for CBL-3195 fix
+            //for (char letter = 'a'; letter <= 'z'; letter++) {
+            //    Db.CreateCollection("abc", letter + str).Should().NotBeNull($"Valid scope name '{letter + str}'.");
+            //}
+
+            for (char letter = '0'; letter <= '9'; letter++) {
+                Db.CreateCollection("abc", letter + str).Should().NotBeNull($"Valid scope name '{letter + str}'.");
+            }
+
+            Db.CreateCollection("abc", "-" + str).Should().NotBeNull($"Valid scope name '{"-" + str}'.");
+        }
+
+        [Fact]
+        public void TestScopeNameStartWithIllegalChars()
+        {
+            // None default Collection and Scope Names start with _ and % are prohibited
+            Action badAction = (() => Db.CreateCollection("abc", "_"));
+            badAction.Should().Throw<CouchbaseLiteException>("Invalid scope name '_'.");
+            badAction = (() => Db.CreateCollection("abc", "%"));
+            badAction.Should().Throw<CouchbaseLiteException>("Invalid scope name '%'.");
+        }
+
+        [Fact]
+        public void TestScopeNameContainingIllegalChars()
+        {
+            var str = "ab";
+            /* Create collections with the collection name containing the following characters
+               !, @, #, $, ^, &, *, (, ), +, -, ., <, >, ?, [, ], {, }, =, “, ‘, |, \, /,`,~ are prohibited. */
+            for (char letter = '!'; letter <= '/'; letter++) {
+                if (letter == '%')
+                    return;
+                Action badAction = (() => Db.CreateCollection("abc", str + letter));
+                badAction.Should().Throw<CouchbaseLiteException>($"Invalid scope name '{str + letter}'.");
+            }
+
+            for (char letter = '<'; letter <= '@'; letter++) {
+                Action badAction = (() => Db.CreateCollection("abc", str + letter));
+                badAction.Should().Throw<CouchbaseLiteException>($"Invalid scope name '{str + letter}'.");
+            }
+
+            for (char letter = '['; letter <= '`'; letter++) {
+                Action badAction = (() => Db.CreateCollection("abc", str + letter));
+                badAction.Should().Throw<CouchbaseLiteException>($"Invalid scope name '{str + letter}'.");
+            }
+
+            for (char letter = '{'; letter <= '~'; letter++) {
+                Action badAction = (() => Db.CreateCollection("abc", str + letter));
+                badAction.Should().Throw<CouchbaseLiteException>($"Invalid scope name '{str + letter}'.");
+            }
+        }
+
+        [Fact]
+        public void TestScopeNameLength()
+        {
+            /* Collection name should contain valid char with length from 1 to 251 */
+            var collName = "";
+            for (int i = 0; i < 251; i++) {
+                collName += 'c';
+                collName.Length.Should().Be(i + 1);
+                Db.CreateCollection("abc", collName).Should().NotBeNull($"Valid scope '{collName}' length {collName.Length}.");
+            }
+
+            var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_%-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";
+            str.Length.Should().Be(251);
+            Db.CreateCollection("abc", str).Should().NotBeNull($"because the scope name can be length at {str.Length}");
+
+            str += "e";
+            str.Length.Should().Be(252);
+            Action badAction = (() => Db.CreateCollection("abc", str));
+            badAction.Should().Throw<CouchbaseLiteException>($"Invalid scope name '{str}' because the scope name length {str.Length} is over naming length limit.");
+        }
+
+        [Fact] // I think this test case is dup of TestScopeNameWithValidChars
+        public void TestScopeNameCaseSensitive()
+        {
+            Db.CreateCollection("abc", "SCOPE1").Should().NotBeNull();
+            // TODO : wait for CBL-3195 fix
+            //Db.CreateCollection("abc", "scope1").Should().NotBeNull("Should be able to be created because scope name is case sensitive.");
+        }
+
+        [Fact]
+        public void TestCreateThenGetCollectionFromDifferentDatabaseInstance()
+        {
+            var colA = Db.CreateCollection("colA", "scopeA");
+            using (var otherDB = OpenDB(Db.Name)) {
+                //TODO wait for CBL-3298 fix
+                //I am using hasScope to check existance of the scope obj in order to use scope obj to get the collections
+                var cols = otherDB.GetCollections(scope: "scopeA");
+                //cols.Contains(colA).Should().BeTrue();
+            }
+        }
     }
 }


clean up service

clean up service

--- src/Discord.Addons.CommandCache/CommandCacheService.cs
+++ src/Discord.Addons.CommandCache/CommandCacheService.cs
@@ -27,6 +27,9 @@
         /// <exception cref="ArgumentOutOfRangeException">Thrown if capacity is less than 1 and is not -1 (unlimited).</exception>
         public CommandCacheService(DiscordSocketClient client, int capacity = 200, Func<LogMessage, Task> log = null)
         {
+            // Initialise the cache.
+            _cache = new List<KeyValuePair<ulong, ulong>>();
+
             // If a method for logging is supplied, use it, otherwise use a method that does nothing.
             _logger = log ?? (_ => Task.CompletedTask);

@@ -73,7 +76,7 @@
                     }
                     catch (HttpException)
                     {
-                        await _logger(new LogMessage(LogSeverity.Warning, "CommandCacheService", $"{cacheable.Id} deleted but {this[cacheable.Id]} does not exist. Removing from cache."));
+                        await _logger(new LogMessage(LogSeverity.Warning, "CommandCacheService", $"{cacheable.Id} deleted but {this[cacheable.Id]} does not exist."));
                     }
                     finally
                     {
@@ -87,11 +90,7 @@

         ~CommandCacheService()
         {
-            if (_autoClear != null)
-            {
-                _autoClear.Dispose();
-                _autoClear = null;
-            }
+            Dispose();
         }

         /// <summary>
@@ -133,15 +132,12 @@

             set
             {
-                // Get the pair with the matching key or the default.
-                var pair = _cache.FirstOrDefault(p => p.Key == key);
-
                 // If the pair is in the cache, remove it and add the edited version at the same location.
-                if (!pair.Equals(default(KeyValuePair<ulong, ulong>)))
+                if (TryGetPairByKey(key, out KeyValuePair<ulong, ulong> pair))
                 {
                     var index = _cache.IndexOf(pair);
                     _cache.RemoveAt(index);
-                    _cache.Insert(index, new KeyValuePair<ulong, ulong>(key, pair.Value));
+                    _cache.Insert(index, new KeyValuePair<ulong, ulong>(key, value));
                 }

                 // Otherwise throw an exception as the key is not in the cache.
@@ -164,7 +160,7 @@
         {
             if (_cache.Count >= _max && _max != UNLIMITED)
             {
-                // If the number of items in the cacher is greater than or equal to the max and the cache is not unlimited,
+                // If the number of items in the cache is greater than or equal to the max and the cache is not unlimited,
                 // remove items starting from the zeroth element until there are (max - 1) elements in the cache.
                 _cache.RemoveRange(0, (_cache.Count - _max) + 1);
             }
@@ -207,12 +203,9 @@
         /// <param name="key">The key to search for.</param>
         /// <returns>Whether or not the removal operation was successful.</returns>
         public bool Remove(ulong key)
-        {
-            // Get either the pair with the specified key, or the default value for a KeyValuePair<ulong, ulong>.
-            var pair = _cache.FirstOrDefault(p => p.Key == key);
-
-            // If pair is not the default, try to remove it.
-            if (!pair.Equals(default(KeyValuePair<ulong, ulong>)))
+        {
+            // If the key is in the cache, try to remove its pair.
+            if (TryGetPairByKey(key, out KeyValuePair<ulong, ulong> pair))
             {
                 return _cache.Remove(pair);
             }
@@ -236,17 +229,14 @@
         /// <returns>Whether or not key was found in the cache.</returns>
         public bool TryGetValue(ulong key, out ulong value)
         {
-            // Get either the matching pair or default.
-            var pair = _cache.FirstOrDefault(p => p.Key == key);
-
-            // If a pair was found, return true and assign its value to the out param.
-            if (!pair.Equals(default(KeyValuePair<ulong, ulong>)))
+            // If the pair is in the cache, set the value and return true..
+            if (TryGetPairByKey(key, out KeyValuePair<ulong, ulong> pair))
             {
                 value = pair.Value;
                 return true;
             }

-            // Otherwise assign 0 and return false.
+            // Otherwise return false and set the value to 0.
             value = 0;
             return false;
         }
@@ -264,5 +254,20 @@
                 _autoClear = null;
             }
         }
+
+        private bool TryGetPairByKey(ulong key, out KeyValuePair<ulong, ulong> pair)
+        {
+            var tryPair = _cache.FirstOrDefault(p => p.Key == key);
+            var defaultPair = default(KeyValuePair<ulong, ulong>);
+
+            if (pair.Equals(defaultPair))
+            {
+                pair = defaultPair;
+                return false;
+            }
+
+            pair = tryPair;
+            return true;
+        }
     }
 }


 * Fixed a crash for some joystick inputs while they're not supported

git-svn-id: e2945e6dc2723cb01f425b5a7c3c201ce5019a89@1019 080cfd25-d5d9-4c59-82ea-70d02a200d8b

--- src/Gablarski.Input.DirectInput/DirectInputProvider.cs
+++ src/Gablarski.Input.DirectInput/DirectInputProvider.cs
@@ -443,8 +443,14 @@
 									{
 										if (!currentButtons.Contains (bd.Offset))
 										{
-											currentInitials[bd.Offset] = bd.Data;
-											currentRanges.Add (bd.Offset, d.Properties.GetRange (ParameterHow.ByOffset, bd.Offset));
+											try
+											{
+												currentRanges.Add (bd.Offset, d.Properties.GetRange (ParameterHow.ByOffset, bd.Offset));
+												currentInitials[bd.Offset] = bd.Data;
+											}
+											catch (UnsupportedException)
+											{
+											}
 										}
 										else
 											OnNewRecording (new RecordingEventArgs (this, String.Format ("{0}|{1}", d.DeviceInformation.InstanceGuid, bd.Offset)));


Using LogVerbose instead of LogInformation

--- src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs
+++ src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs
@@ -137,7 +137,7 @@
                 return;
             }

-            _logger.LogInformation(
+            _logger.LogVerbose(
                 "Request successfully matched the route with name '{RouteName}' and template '{RouteTemplate}'.",
                 Name,
                 RouteTemplate);


version bump for crashfix

version bump for crashfix

--- slimCat/Utilities/Constants.cs
+++ slimCat/Utilities/Constants.cs
@@ -382,7 +382,7 @@
         /// <summary>
         ///     The version of the client.
         /// </summary>
-        public const double Version = 5.002;
+        public const double Version = 5.003;

         /// <summary>
         ///     The endpoint for F-chat websocket communication.


v2.123.0

--- src/Microsoft.VisualStudio.Services.Agent/Constants.cs
+++ src/Microsoft.VisualStudio.Services.Agent/Constants.cs
@@ -44,7 +44,7 @@

         public static class Agent
         {
-            public static readonly string Version = "2.122.1";
+            public static readonly string Version = "2.123.0";

 #if OS_LINUX
             public static readonly OSPlatform Platform = OSPlatform.Linux;


Add exception reporting when unloading AppDomain and elminate deletion of shadowcopy cache

--- src/NUnitEngine/nunit.engine/Services/DomainManager.cs
+++ src/NUnitEngine/nunit.engine/Services/DomainManager.cs
@@ -145,62 +145,61 @@
         #region Nested DomainUnloader Class
         class DomainUnloader
         {
-            private Thread thread;
-            private AppDomain domain;
+            private Thread _unloadThread;
+            private AppDomain _domain;
+            private Exception _unloadException;

             public DomainUnloader(AppDomain domain)
             {
-                this.domain = domain;
+                _domain = domain;
             }

             public void Unload()
             {
-                string domainName;
+                _unloadThread = new Thread(new ThreadStart(UnloadOnThread));
+
+                _unloadThread.Start();
+
+                if (!_unloadThread.Join(30000))
+                {
+                    string msg = "Unable to unload AppDomain, Unload thread timed out";
+
+                    log.Error(msg);
+                    _unloadThread.Abort();
+
+                    throw new NUnitEngineException(msg);
+                }
+
+                if (_unloadException != null)
+                    throw new NUnitEngineException("Exception encountered unloading AppDomain", _unloadException);
+            }
+
+            private void UnloadOnThread()
+            {
+                bool shadowCopy = false;
+                string domainName = "UNKNOWN";
+
                 try
                 {
-                    domainName = "UNKNOWN";//domain.FriendlyName;
-                }
-                catch (AppDomainUnloadedException)
-                {
-                    return;
-                }
-
-                log.Info("Unloading AppDomain " + domainName);
-
-                thread = new Thread(new ThreadStart(UnloadOnThread));
-                thread.Start();
-                if (!thread.Join(30000))
-                {
-                    log.Error("Unable to unload AppDomain {0}, Unload thread timed out", domainName);
-                    thread.Abort();
-                }
-            }
-
-            private void UnloadOnThread()
-            {
-                bool shadowCopy = false;
-                string cachePath = null;
-                string domainName = "UNKNOWN";
-
-                try
-                {
-                    shadowCopy = domain.ShadowCopyFiles;
-                    cachePath = domain.SetupInformation.CachePath;
-                    domainName = domain.FriendlyName;
-
-                    AppDomain.Unload(domain);
+                    shadowCopy = _domain.ShadowCopyFiles;
+                    domainName = _domain.FriendlyName;
+
+                    // Uncomment to simulate an error in unloading
+                    //throw new Exception("Testing");
+
+                    // Uncomment to simulate a timeout while unloading
+                    //while (true) ;
+
+                    AppDomain.Unload(_domain);
                 }
                 catch (Exception ex)
                 {
+                    _unloadException = ex;
+
                     // We assume that the tests did something bad and just leave
                     // the orphaned AppDomain "out there".
                     // TODO: Something useful.
                     log.Error("Unable to unload AppDomain " + domainName, ex);
-                }
-                finally
-                {
-                    if (shadowCopy && cachePath != null)
-                        DeleteCacheDir(new DirectoryInfo(cachePath));
                 }
             }
         }
@@ -296,60 +295,6 @@
             return cachePath;
         }

-        /// <summary>
-        /// Helper method to delete the cache dir. This method deals
-        /// with a bug that occurs when files are marked read-only
-        /// and deletes each file separately in order to give better
-        /// exception information when problems occur.
-        ///
-        /// TODO: This entire method is problematic. Should we be doing it?
-        /// </summary>
-        /// <param name="cacheDir"></param>
-        private static void DeleteCacheDir( DirectoryInfo cacheDir )
-        {
-            //			Debug.WriteLine( "Modules:");
-            //			foreach( ProcessModule module in Process.GetCurrentProcess().Modules )
-            //				Debug.WriteLine( module.ModuleName );
-
-
-            if(cacheDir.Exists)
-            {
-                foreach( DirectoryInfo dirInfo in cacheDir.GetDirectories() )
-                    DeleteCacheDir( dirInfo );
-
-                foreach( FileInfo fileInfo in cacheDir.GetFiles() )
-                {
-                    fileInfo.Attributes = FileAttributes.Normal;
-                    try
-                    {
-                        fileInfo.Delete();
-                    }
-                    catch( Exception ex )
-                    {
-                        Debug.WriteLine( string.Format(
-                            "Error deleting {0}, {1}", fileInfo.Name, ex.Message ) );
-                    }
-                }
-
-                cacheDir.Attributes = FileAttributes.Normal;
-
-                try
-                {
-                    cacheDir.Delete();
-                }
-                catch( Exception ex )
-                {
-                    Debug.WriteLine( string.Format(
-                        "Error deleting {0}, {1}", cacheDir.Name, ex.Message ) );
-                }
-            }
-        }
-
-        private bool IsTestDomain(AppDomain domain)
-        {
-            return domain.FriendlyName.StartsWith( "test-domain-" );
-        }
-
         public static string GetCommonAppBase(IList<TestPackage> packages)
         {
             var assemblies = new List<string>();


Changed few emojis

Changed few emojis

- changed emojis to respective tasks such as deletions now have trash emoji.
- removed `highlighting` from created/ deleted channel IDs to make it easier to copy without getting blank spaces or full-stop.

--- src/NadekoBot/Modules/Administration/Administration.cs
+++ src/NadekoBot/Modules/Administration/Administration.cs
@@ -577,7 +577,7 @@
         public async Task DelVoiChanl(IUserMessage umsg, [Remainder] IVoiceChannel voiceChannel)
         {
             await voiceChannel.DeleteAsync().ConfigureAwait(false);
-            await umsg.Channel.SendMessageAsync($"❗Removed voice channel **{voiceChannel.Name}** successfully.").ConfigureAwait(false);
+            await umsg.Channel.SendMessageAsync($"🗑 Removed voice channel **{voiceChannel.Name}** successfully.").ConfigureAwait(false);
         }

         [NadekoCommand, Usage, Description, Aliases]
@@ -587,7 +587,7 @@
         {
             var channel = (ITextChannel)umsg.Channel;
             var ch = await channel.Guild.CreateVoiceChannelAsync(channelName).ConfigureAwait(false);
-            await channel.SendMessageAsync($"✅ Created voice channel **{ch.Name}**, ID `{ch.Id}`.").ConfigureAwait(false);
+            await channel.SendMessageAsync($"✅ Created voice channel **{ch.Name}**, ID: {ch.Id}.").ConfigureAwait(false);
         }

         [NadekoCommand, Usage, Description, Aliases]
@@ -596,7 +596,7 @@
         public async Task DelTxtChanl(IUserMessage umsg, [Remainder] ITextChannel toDelete)
         {
             await toDelete.DeleteAsync().ConfigureAwait(false);
-            await umsg.Channel.SendMessageAsync($"❗Removed text channel **{toDelete.Name}**, ID `{toDelete.Id}`.").ConfigureAwait(false);
+            await umsg.Channel.SendMessageAsync($"🗑 Removed text channel **{toDelete.Name}**, ID: {toDelete.Id}.").ConfigureAwait(false);
         }

         [NadekoCommand, Usage, Description, Aliases]
@@ -606,7 +606,7 @@
         {
             var channel = (ITextChannel)umsg.Channel;
             var txtCh = await channel.Guild.CreateTextChannelAsync(channelName).ConfigureAwait(false);
-            await channel.SendMessageAsync($"✅ Added text channel **{txtCh.Name}**, ID `{txtCh.Id}`.").ConfigureAwait(false);
+            await channel.SendMessageAsync($"✅ Added text channel **{txtCh.Name}**, ID: {txtCh.Id}.").ConfigureAwait(false);
         }

         [NadekoCommand, Usage, Description, Aliases]
@@ -693,7 +693,7 @@

             await (await NadekoBot.Client.GetCurrentUserAsync()).ModifyAsync(u => u.Username = newName).ConfigureAwait(false);

-            await channel.SendMessageAsync($"🆒 Successfully changed name to **{newName}**").ConfigureAwait(false);
+            await channel.SendMessageAsync($"ℹ Successfully changed name to **{newName}**").ConfigureAwait(false);
         }

         [NadekoCommand, Usage, Description, Aliases]


Add null checking before updating the bookLoan entity in [HttpPost]Return.

--- src/Open-School-Library/Controllers/BooksController.cs
+++ src/Open-School-Library/Controllers/BooksController.cs
@@ -340,26 +340,30 @@

             if (ModelState.IsValid && isBookCheckedOut(model.BookID) == true)
             {
-                var data = _context.BookLoans.Where(x => x.BookLoanID == model.BookLoanID).FirstOrDefault();
-
-                data.BookLoanID = model.BookLoanID;
-                data.BookID = model.BookID;
-                data.StudentID = model.StudentID;
-                data.CheckedOutOn = (DateTime)model.CheckedOutOn;
-                data.DueOn = (DateTime)model.AvailableOn;
-                data.ReturnedOn = DateTime.Now;
-
-                try
-                {
-                    _context.Update(data);
-                    await _context.SaveChangesAsync();
+                var bookLoan = _context.BookLoans.Where(x => x.BookLoanID == model.BookLoanID).FirstOrDefault();
+
+                if(bookLoan != null)
+                {
+                    bookLoan.BookLoanID = model.BookLoanID;
+                    bookLoan.BookID = model.BookID;
+                    bookLoan.StudentID = model.StudentID;
+                    bookLoan.CheckedOutOn = (DateTime)model.CheckedOutOn;
+                    bookLoan.DueOn = (DateTime)model.AvailableOn;
+                    bookLoan.ReturnedOn = DateTime.Now;
+
+                    try
+                    {
+                        _context.Update(bookLoan);
+                        await _context.SaveChangesAsync();
+                    }
+                    catch (DbUpdateConcurrencyException)
+                    {
+                        //TODO Add logging and error handling. - Christopher
+                    }
+
+                    return RedirectToAction("Index");
                 }
-                catch (DbUpdateConcurrencyException)
-                {
-
-                }
-
-                return RedirectToAction("Index");
+
             }
             else
             {


- Added vhost safe guard

- Added vhost safe guard

--- src/OpenDataApplication/OpenDataApplication/Program.cs
+++ src/OpenDataApplication/OpenDataApplication/Program.cs
@@ -9,6 +9,7 @@
         [STAThread]
         public static void Main()
         {
+            if (System.Diagnostics.Debugger.IsAttached) throw new InvalidOperationException("Do not run in an IDE!");
 #if DEBUG
             bool release = false;
 #else


wrapped members excluded from code coverage

--- src/Selenium.WebDriver.Extensions.Shared/WebElement.cs
+++ src/Selenium.WebDriver.Extensions.Shared/WebElement.cs
@@ -44,7 +44,10 @@
         /// <summary>
         /// Gets the <see cref="IWebDriver"/> used to find this element.
         /// </summary>
-        public IWebDriver WrappedDriver
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
+        public virtual IWebDriver WrappedDriver
         {
             get
             {
@@ -55,6 +58,9 @@
         /// <summary>
         /// Gets the tag name of this element.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public string TagName
         {
             get
@@ -67,6 +73,9 @@
         /// Gets the innerText of this element, without any leading or trailing whitespace, and with other whitespace
         /// collapsed.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public string Text
         {
             get
@@ -78,6 +87,9 @@
         /// <summary>
         /// Gets a value indicating whether or not this element is enabled.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public bool Enabled
         {
             get
@@ -89,6 +101,9 @@
         /// <summary>
         /// Gets a value indicating whether or not this element is selected.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public bool Selected
         {
             get
@@ -101,6 +116,9 @@
         /// Gets a <see cref="Point"/> object containing the coordinates of the upper-left corner of this element
         /// relative to the upper-left corner of the page.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public Point Location
         {
             get
@@ -112,6 +130,9 @@
         /// <summary>
         /// Gets a <see cref="Size"/> object containing the height and width of this element.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public Size Size
         {
             get
@@ -123,6 +144,9 @@
         /// <summary>
         /// Gets a value indicating whether or not this element is displayed.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public bool Displayed
         {
             get
@@ -136,6 +160,9 @@
         /// </summary>
         /// <param name="by">The locating mechanism to use.</param>
         /// <returns>The first matching <see cref="IWebElement"/> on the current context.</returns>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public IWebElement FindElement(By by)
         {
             return this.InnerElement.FindElement(by);
@@ -149,6 +176,9 @@
         /// A <see cref="ReadOnlyCollection{IWebElement}"/> of all <see cref="IWebElement">WebElements</see>
         /// matching the current criteria, or an empty list if nothing matches.
         /// </returns>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public ReadOnlyCollection<IWebElement> FindElements(By @by)
         {
             return this.InnerElement.FindElements(by);
@@ -157,6 +187,9 @@
         /// <summary>
         /// Clears the content of this element.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public void Clear()
         {
             this.InnerElement.Clear();
@@ -166,6 +199,9 @@
         /// Simulates typing text into the element.
         /// </summary>
         /// <param name="text">The text to type into the element.</param>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public void SendKeys(string text)
         {
             this.InnerElement.Clear();
@@ -174,6 +210,9 @@
         /// <summary>
         /// Submits this element to the web server.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public void Submit()
         {
             this.InnerElement.Submit();
@@ -182,6 +221,9 @@
         /// <summary>
         /// Clicks this element.
         /// </summary>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public void Click()
         {
             this.InnerElement.Click();
@@ -192,6 +234,9 @@
         /// </summary>
         /// <param name="attributeName">The name of the attribute.</param>
         /// <returns>The attribute's current value. Returns a <see langword="null"/> if the value is not set.</returns>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public string GetAttribute(string attributeName)
         {
             return this.InnerElement.GetAttribute(attributeName);
@@ -202,6 +247,9 @@
         /// </summary>
         /// <param name="propertyName">The name of the CSS property to get the value of.</param>
         /// <returns>The value of the specified CSS property.</returns>
+#if !NET35
+        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
         public string GetCssValue(string propertyName)
         {
             return this.InnerElement.GetCssValue(propertyName);


Compiler: Simplified ResolveGenericsVisitor (should have better performance too).

--- src/SharpLang.Compiler/Cecil/ResolveGenericsVisitor.cs
+++ src/SharpLang.Compiler/Cecil/ResolveGenericsVisitor.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections.Generic;
 using Mono.Cecil;

 namespace SharpLang.CompilerServices.Cecil
@@ -10,11 +9,18 @@
     /// </summary>
     class ResolveGenericsVisitor : TypeReferenceVisitor
     {
-        private Dictionary<TypeReference, TypeReference> genericTypeMapping;
+        private GenericInstanceMethod genericContextMethod;
+        private GenericInstanceType genericContextType;

-        public ResolveGenericsVisitor(Dictionary<TypeReference, TypeReference> genericTypeMapping)
+        public ResolveGenericsVisitor(MethodReference genericContext)
         {
-            this.genericTypeMapping = genericTypeMapping;
+            genericContextMethod = genericContext as GenericInstanceMethod;
+            genericContextType = genericContext.DeclaringType as GenericInstanceType;
+        }
+
+        public ResolveGenericsVisitor(TypeReference genericContext)
+        {
+            genericContextType = genericContext as GenericInstanceType;
         }

         /// <summary>
@@ -30,16 +36,8 @@
             if (genericInstanceTypeContext == null)
                 return type;

-            // Build dictionary that will map generic type to their real implementation type
-            var resolvedType = genericInstanceTypeContext.Resolve();
-            var genericTypeMapping = new Dictionary<TypeReference, TypeReference>();
-            for (int i = 0; i < resolvedType.GenericParameters.Count; ++i)
-            {
-                var genericParameter = resolvedType.GenericParameters[i];
-                genericTypeMapping.Add(genericParameter, genericInstanceTypeContext.GenericArguments[i]);
-            }
-
-            var visitor = new ResolveGenericsVisitor(genericTypeMapping);
+            // Visit recursively and replace generic parameters with generic arguments from context
+            var visitor = new ResolveGenericsVisitor(context);
             var result = visitor.VisitDynamic(type);

             // Make sure type is closed now
@@ -63,43 +61,13 @@
             if (context == null)
                 return type;

+            // Visit recursively and replace generic parameters with generic arguments from context
             var genericInstanceTypeContext = context.DeclaringType as GenericInstanceType;
             var genericInstanceMethodContext = context as GenericInstanceMethod;
             if (genericInstanceMethodContext == null && genericInstanceTypeContext == null)
                 return type;

-            // Build dictionary that will map generic type to their real implementation type
-            var genericTypeMapping = new Dictionary<TypeReference, TypeReference>(TypeReferenceComparer.Default);
-            if (genericInstanceTypeContext != null)
-            {
-                var resolvedType1 = genericInstanceTypeContext.ElementType;
-                var resolvedType2 = genericInstanceTypeContext.Resolve();
-                for (int i = 0; i < resolvedType1.GenericParameters.Count; ++i)
-                {
-                    var genericParameter1 = resolvedType1.GenericParameters[i];
-                    var genericParameter2 = resolvedType2.GenericParameters[i];
-                    if (genericParameter2 != genericParameter1)
-                        genericTypeMapping.Add(genericParameter1, genericParameter2);
-                }
-            }
-
-            if (genericInstanceMethodContext != null)
-            {
-                var elementMethod = genericInstanceMethodContext.ElementMethod;
-                var resolvedMethod = genericInstanceMethodContext.Resolve();
-                for (int i = 0; i < elementMethod.GenericParameters.Count; ++i)
-                {
-                    var genericParameter1 = elementMethod.GenericParameters[i];
-                    var genericParameter2 = resolvedMethod.GenericParameters[i];
-                    if (genericParameter2 != genericParameter1)
-                        genericTypeMapping.Add(genericParameter1, genericParameter2);
-                }
-            }
-
-            if (genericTypeMapping.Count == 0)
-                return type;
-
-            var visitor = new ResolveGenericsVisitor(genericTypeMapping);
+            var visitor = new ResolveGenericsVisitor(context);
             var result = visitor.VisitDynamic(type);

             return result;
@@ -113,48 +81,14 @@
             if (context == null)
                 return type;

+            // Visit recursively and replace generic parameters with generic arguments from context
             var genericInstanceTypeContext = context.DeclaringType as GenericInstanceType;
             var genericInstanceMethodContext = context as GenericInstanceMethod;
             if (genericInstanceMethodContext == null && genericInstanceTypeContext == null)
                 return type;

-            // Build dictionary that will map generic type to their real implementation type
-            var genericTypeMapping = new Dictionary<TypeReference, TypeReference>(TypeReferenceComparer.Default);
-            if (genericInstanceTypeContext != null)
-            {
-                var resolvedType1 = genericInstanceTypeContext.ElementType;
-                var resolvedType2 = genericInstanceTypeContext.Resolve();
-                for (int i = 0; i < resolvedType1.GenericParameters.Count; ++i)
-                {
-                    var genericParameter1 = resolvedType1.GenericParameters[i];
-                    var genericParameter2 = resolvedType2.GenericParameters[i];
-                    genericTypeMapping.Add(genericParameter1, genericInstanceTypeContext.GenericArguments[i]);
-                    if (genericParameter2 != genericParameter1)
-                        genericTypeMapping.Add(genericParameter2, genericInstanceTypeContext.GenericArguments[i]);
-                }
-            }
-
-            if (genericInstanceMethodContext != null)
-            {
-                var elementMethod = genericInstanceMethodContext.ElementMethod;
-                var resolvedMethod = genericInstanceMethodContext.Resolve();
-                for (int i = 0; i < elementMethod.GenericParameters.Count; ++i)
-                {
-                    var genericParameter = elementMethod.GenericParameters[i];
-                    genericTypeMapping.Add(genericParameter, genericInstanceMethodContext.GenericArguments[i]);
-
-                    var genericParameter2 = resolvedMethod.GenericParameters[i];
-                    if (genericParameter != genericParameter2)
-                        genericTypeMapping.Add(genericParameter2, genericInstanceMethodContext.GenericArguments[i]);
-                }
-            }
-
-            var visitor = new ResolveGenericsVisitor(genericTypeMapping);
+            var visitor = new ResolveGenericsVisitor(context);
             var result = visitor.VisitDynamic(type);
-
-            // Make sure type is closed now
-            //if (result.ContainsGenericParameter())
-            //    throw new InvalidOperationException("Unsupported generic resolution.");

             return result;
         }
@@ -194,21 +128,6 @@
                 result2.GenericArguments.Add(Process(context, genericArgument));

             return result2;
-            //else
-            //{
-            //    result = new MethodReference(method.Name, Process(context, method.ReturnType), Process(context, method.DeclaringType))
-            //    {
-            //        HasThis = method.HasThis,
-            //        ExplicitThis = method.ExplicitThis,
-            //        CallingConvention = method.CallingConvention,
-            //    };
-            //
-            //    foreach (var parameter in method.Parameters)
-            //        result.Parameters.Add(new ParameterDefinition(Process(context, parameter.ParameterType)));
-            //}
-            //
-            //foreach (var generic_parameter in method.GenericParameters)
-            //    result.GenericParameters.Add(new GenericParameter(generic_parameter.Name, result));
         }

         public static bool ContainsGenericParameters(MethodReference method)
@@ -239,26 +158,42 @@

         public override TypeReference Visit(GenericParameter type)
         {
-            TypeReference result;
-            if (genericTypeMapping.TryGetValue(type, out result))
-                return result;
+            if (type.Type == GenericParameterType.Method)
+            {
+                if (genericContextMethod != null && type.Position < genericContextMethod.GenericArguments.Count)
+                {
+                    // Look for generic parameter in both resolved and element method
+                    var genericContext1 = genericContextMethod.Resolve();
+                    var genericContext2 = genericContextMethod.ElementMethod;
+
+                    var genericParameter = genericContext1.GenericParameters[type.Position];
+                    if (genericParameter.Name == type.Name)
+                        return genericContextMethod.GenericArguments[type.Position];
+
+                    genericParameter = genericContext2.GenericParameters[type.Position];
+                    if (genericParameter.Name == type.Name)
+                        return genericContextMethod.GenericArguments[type.Position];
+                }
+            }
+            else
+            {
+                if (genericContextType != null && type.Position < genericContextType.GenericArguments.Count)
+                {
+                    // Look for generic parameter in both resolved and element method
+                    var genericContext1 = genericContextType.Resolve();
+                    var genericContext2 = genericContextType.ElementType;
+
+                    var genericParameter = genericContext1.GenericParameters[type.Position];
+                    if (genericParameter.Name == type.Name)
+                        return genericContextType.GenericArguments[type.Position];
+
+                    genericParameter = genericContext2.GenericParameters[type.Position];
+                    if (genericParameter.Name == type.Name)
+                        return genericContextType.GenericArguments[type.Position];
+                }
+            }

             return base.Visit(type);
         }
-
-        class TypeReferenceComparer : EqualityComparer<TypeReference>
-        {
-            public static readonly EqualityComparer<TypeReference> Default =  new TypeReferenceComparer();
-
-            public override bool Equals(TypeReference x, TypeReference y)
-            {
-                return x.FullName == y.FullName;
-            }
-
-            public override int GetHashCode(TypeReference obj)
-            {
-                return obj.FullName.GetHashCode();
-            }
-        }
     }
 }


Renamed solutionPath to modelSavePath

Renamed solutionPath to modelSavePath

--- src/SourceBrowser.Site/Controllers/UploadController.cs
+++ src/SourceBrowser.Site/Controllers/UploadController.cs
@@ -45,10 +45,11 @@
             foreach (var path in solutionPaths)
             {
                 var solutionName = Path.GetFileName(path);
-                var solutionPath = Path.Combine(repoPath, solutionName);
+                var modelSavePath = Path.Combine(repoPath, solutionName);
                 var sourceGenerator = new Generator.SolutionAnalayzer(path);
+
                 //Build the workspace
-                var workspaceModel = sourceGenerator.BuildWorkspaceModel(solutionPath);
+                var workspaceModel = sourceGenerator.BuildWorkspaceModel(modelSavePath);

                 //One pass to lookup all declarations
                 var typeTransformer = new TokenLookupTransformer();


For mobile the mobile app, we would like to take only last 3 years of data; but for web we want everything

--- src/StatisticsRomania.Repository/Seeders/BaseSeeder.cs
+++ src/StatisticsRomania.Repository/Seeders/BaseSeeder.cs
@@ -59,7 +59,8 @@

             var resourceKeys = typeof(CountiesData).GetProperties(BindingFlags.NonPublic | BindingFlags.Static).Where(x => x.Name.EndsWith($"{seederTypeName}Seeder")).Select(x => (string)x.GetValue(null)).ToList();
             resourceKeys.Sort();
-            resourceKeys = resourceKeys.Skip(resourceKeys.Count - 3).ToList();
+            // TODO: if mobile, we would like to take only last 3 years; but for web we want everything
+            //resourceKeys = resourceKeys.Skip(resourceKeys.Count - 3).ToList();

             var res = new List<string>();


Fix flaky test (#37106)

Fix flaky test (#37106)

- Synchronize reads and writes using a tcs.

--- src/System.IO.Pipelines/tests/StreamPipeWriterTests.cs
+++ src/System.IO.Pipelines/tests/StreamPipeWriterTests.cs
@@ -95,20 +95,24 @@
         [Fact]
         public async Task CanDoMultipleAsyncWritesToStream()
         {
-            var pipe = new Pipe(new PipeOptions(readerScheduler: PipeScheduler.Inline));
+            var pipe = new Pipe();
             PipeWriter writer = PipeWriter.Create(pipe.Writer.AsStream());
-
-            static async Task DoWritesAsync(PipeWriter writer, byte[][] writes)
+            // This needs to run inline to synchronize the reader and writer
+            TaskCompletionSource<object> waitForRead = null;
+
+            async Task DoWritesAsync(PipeWriter writer, byte[][] writes)
             {
                 for (int i = 0; i < writes.Length; i++)
                 {
+                    waitForRead = new TaskCompletionSource<object>();
                     await writer.WriteAsync(writes[i]);
+                    await waitForRead.Task;
                 }

                 writer.Complete();
             }

-            static async Task DoReadsAsync(PipeReader reader, byte[][] reads)
+            async Task DoReadsAsync(PipeReader reader, byte[][] reads)
             {
                 int index = 0;
                 while (true)
@@ -122,6 +126,7 @@
                     Assert.Equal(reads[index], buffer.ToArray());
                     reader.AdvanceTo(buffer.End);
                     index++;
+                    waitForRead.TrySetResult(null);
                 }

                 reader.Complete();


Clean up reference emit order

Clean up reference emit order

This cleans up the emit order for references to ensure Compilation
values are always emitted as Compilation.  Indirect values that refer to
the Compilation simply use the data emitted by the Compilation.

--- src/Test/Utilities/Desktop/HostedRuntimeEnvironment.cs
+++ src/Test/Utilities/Desktop/HostedRuntimeEnvironment.cs
@@ -32,12 +32,6 @@
             }
         }

-        private sealed class EmitTracker
-        {
-            internal readonly List<ModuleData> Dependencies = new List<ModuleData>();
-            internal readonly HashSet<Compilation> CompilationSet = new HashSet<Compilation>();
-        }
-
         private bool _disposed;
         private AppDomain _domain;
         private RuntimeAssemblyManager _assemblyManager;
@@ -110,81 +104,101 @@
             }
         }

-        private static void EmitDependentCompilation(Compilation compilation,
-                                                     EmitTracker tracker,
-                                                     DiagnosticBag diagnostics,
-                                                     bool usePdbForDebugging = false)
-        {
-            // It is possible for the same Compilation to appear multiple times
-            // as a dependent reference in a Compilation.  Only need to emit it
-            // once.
-            if (tracker.CompilationSet.Contains(compilation))
-            {
-                return;
-            }
-
-            tracker.CompilationSet.Add(compilation);
-
-            var emitData = EmitCompilation(compilation, null, tracker, diagnostics, null);
-            if (emitData.HasValue)
-            {
-                var moduleData = new ModuleData(compilation.Assembly.Identity,
-                                                OutputKind.DynamicallyLinkedLibrary,
-                                                emitData.Value.Assembly,
-                                                pdb: usePdbForDebugging ? emitData.Value.Pdb : default(ImmutableArray<byte>),
-                                                inMemoryModule: true);
-                tracker.Dependencies.Add(moduleData);
-            }
-        }
-
-        private static void EmitReferences(Compilation compilation, EmitTracker tracker, DiagnosticBag diagnostics)
+        /// <summary>
+        /// Find all of the <see cref="Compilation"/> values reachable from this instance.
+        /// </summary>
+        /// <param name="compilation"></param>
+        /// <returns></returns>
+        private static List<Compilation> FindReferencedCompilations(Compilation original)
+        {
+            var list = new List<Compilation>();
+            var toVisit = new Queue<Compilation>(FindDirectReferencedCompilations(original));
+
+            while (toVisit.Count > 0)
+            {
+                var current = toVisit.Dequeue();
+                if (list.Contains(current))
+                {
+                    continue;
+                }
+
+                list.Add(current);
+
+                foreach (var other in FindDirectReferencedCompilations(current))
+                {
+                    toVisit.Enqueue(other);
+                }
+            }
+
+            return list;
+        }
+
+        private static List<Compilation> FindDirectReferencedCompilations(Compilation compilation)
+        {
+            var list = new List<Compilation>();
+            var previousCompilation = compilation.ScriptCompilationInfo?.PreviousScriptCompilation;
+            if (previousCompilation != null)
+            {
+                list.Add(previousCompilation);
+            }
+
+            foreach (var reference in compilation.References.OfType<CompilationReference>())
+            {
+                list.Add(reference.Compilation);
+            }
+
+            return list;
+        }
+
+        /// <summary>
+        /// Emit all of the references which are not directly or indirectly a <see cref="Compilation"/> value.
+        /// </summary>
+        private static void EmitReferences(Compilation compilation, HashSet<string> fullNameSet, List<ModuleData> dependencies, DiagnosticBag diagnostics)
         {
             var previousSubmission = compilation.ScriptCompilationInfo?.PreviousScriptCompilation;
-            if (previousSubmission != null)
-            {
-                EmitDependentCompilation(previousSubmission, tracker, diagnostics);
-            }
-
-            foreach (MetadataReference r in compilation.References)
-            {
-                CompilationReference compilationRef;
-                PortableExecutableReference peRef;
-
-                if ((compilationRef = r as CompilationReference) != null)
-                {
-                    EmitDependentCompilation(compilationRef.Compilation, tracker, diagnostics);
-                }
-                else if ((peRef = r as PortableExecutableReference) != null)
-                {
-                    var metadata = peRef.GetMetadata();
-                    bool isManifestModule = peRef.Properties.Kind == MetadataImageKind.Assembly;
-                    foreach (var module in EnumerateModules(metadata))
+            foreach (var metadataReference in compilation.References)
+            {
+                if (metadataReference is CompilationReference)
+                {
+                    continue;
+                }
+
+                var peRef = (PortableExecutableReference)metadataReference;
+                var metadata = peRef.GetMetadata();
+                var isManifestModule = peRef.Properties.Kind == MetadataImageKind.Assembly;
+                var identity = isManifestModule
+                    ? ((AssemblyMetadata)metadata).GetAssembly().Identity
+                    : null;
+
+                // If this is an indirect reference to a Compilation then it is already been emitted
+                // so no more work to be done.
+                if (isManifestModule && fullNameSet.Contains(identity.GetDisplayName()))
+                {
+                    continue;
+                }
+
+                foreach (var module in EnumerateModules(metadata))
+                {
+                    ImmutableArray<byte> bytes = module.Module.PEReaderOpt.GetEntireImage().GetContent();
+                    ModuleData moduleData;
+                    if (isManifestModule)
                     {
-                        ImmutableArray<byte> bytes = module.Module.PEReaderOpt.GetEntireImage().GetContent();
-                        ModuleData moduleData;
-                        if (isManifestModule)
-                        {
-                            moduleData = new ModuleData(((AssemblyMetadata)metadata).GetAssembly().Identity,
-                                                            OutputKind.DynamicallyLinkedLibrary,
-                                                            bytes,
-                                                            pdb: default(ImmutableArray<byte>),
-                                                            inMemoryModule: true);
-                        }
-                        else
-                        {
-                            moduleData = new ModuleData(module.Name,
-                                                            bytes,
-                                                            pdb: default(ImmutableArray<byte>),
-                                                            inMemoryModule: true);
-                        }
-
-                        tracker.Dependencies.Add(moduleData);
-                        isManifestModule = false;
+                        moduleData = new ModuleData(identity,
+                                                    OutputKind.DynamicallyLinkedLibrary,
+                                                    bytes,
+                                                    pdb: default(ImmutableArray<byte>),
+                                                    inMemoryModule: true);
                     }
-                }
-                else
-                {
-                    throw new InvalidOperationException();
+                    else
+                    {
+                        moduleData = new ModuleData(module.Name,
+                                                    bytes,
+                                                    pdb: default(ImmutableArray<byte>),
+                                                    inMemoryModule: true);
+                    }
+
+                    dependencies.Add(moduleData);
+                    isManifestModule = false;
                 }
             }
         }
@@ -197,13 +211,48 @@
         private static EmitData? EmitCompilation(
             Compilation compilation,
             IEnumerable<ResourceDescription> manifestResources,
-            EmitTracker tracker,
+            List<ModuleData> dependencies,
             DiagnosticBag diagnostics,
             CompilationTestData testData
         )
         {
-            EmitReferences(compilation, tracker, diagnostics);
-
+            // A Compilation can appear multiple times in a depnedency graph as both a Compilation and as a MetadataReference
+            // value.  Iterate the Compilations eagerly so they are always emitted directly and later references can re-use
+            // the value.  This gives better, and consistent, diagostic information.
+            var referencedCompilations = FindReferencedCompilations(compilation);
+            var fullNameSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+
+            foreach (var referencedCompilation in referencedCompilations)
+            {
+                var emitData = EmitCompilationCore(referencedCompilation, null, diagnostics, null);
+                if (emitData.HasValue)
+                {
+                    var moduleData = new ModuleData(referencedCompilation.Assembly.Identity,
+                                                    OutputKind.DynamicallyLinkedLibrary,
+                                                    emitData.Value.Assembly,
+                                                    pdb: default(ImmutableArray<byte>),
+                                                    inMemoryModule: true);
+                    fullNameSet.Add(moduleData.Id.FullName);
+                    dependencies.Add(moduleData);
+                }
+            }
+
+            // Now that the Compilation values have been emitted, emit the non-compilation references
+            foreach (var current in (new[] { compilation }).Concat(referencedCompilations))
+            {
+                EmitReferences(current, fullNameSet, dependencies, diagnostics);
+            }
+
+            return EmitCompilationCore(compilation, manifestResources, diagnostics, testData);
+        }
+
+        private static EmitData? EmitCompilationCore(
+            Compilation compilation,
+            IEnumerable<ResourceDescription> manifestResources,
+            DiagnosticBag diagnostics,
+            CompilationTestData testData
+        )
+        {
             using (var executableStream = new MemoryStream())
             {
                 var pdb = default(ImmutableArray<byte>);
@@ -256,8 +305,8 @@
             _testData.Methods.Clear();

             var diagnostics = DiagnosticBag.GetInstance();
-            var tracker = new EmitTracker();
-            var mainData = EmitCompilation(mainCompilation, manifestResources, tracker, diagnostics, _testData);
+            var dependencies = new List<ModuleData>();
+            var mainData = EmitCompilation(mainCompilation, manifestResources, dependencies, diagnostics, _testData);

             _lazyDiagnostics = diagnostics.ToReadOnlyAndFree();

@@ -271,18 +320,18 @@
                                                  pdb: usePdbForDebugging ? mainPdb : default(ImmutableArray<byte>),
                                                  inMemoryModule: true);
                 _mainModulePdb = mainPdb;
-                _allModuleData = tracker.Dependencies;
+                _allModuleData = dependencies;
                 _allModuleData.Insert(0, _mainModule);
-                CreateAssemblyManager(tracker.Dependencies, _mainModule);
+                CreateAssemblyManager(dependencies, _mainModule);
             }
             else
             {
                 string dumpDir;
-                RuntimeAssemblyManager.DumpAssemblyData(tracker.Dependencies, out dumpDir);
+                RuntimeAssemblyManager.DumpAssemblyData(dependencies, out dumpDir);

                 // This method MUST throw if compilation did not succeed.  If compilation succeeded and there were errors, that is bad.
                 // Please see KevinH if you intend to change this behavior as many tests expect the Exception to indicate failure.
-                throw new EmitException(_lazyDiagnostics, dumpDir);
+                throw new EmitException(_lazyDiagnostics, dumpDir);
             }
         }


Fix ConfigurationsRights.List not being a power of 2

--- src/Tgstation.Server.Api/Rights/ConfigurationRights.cs
+++ src/Tgstation.Server.Api/Rights/ConfigurationRights.cs
@@ -23,6 +23,6 @@
 		/// <summary>
 		/// User may list files
 		/// </summary>
-		List = 3
+		List = 4
 	}
 }


Rework for #3866

Rework for #3866

--- src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs
+++ src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs
@@ -610,7 +610,7 @@
         public class Result
         {
             /// <summary>
-            /// Gets or sets ... fixme
+            /// Gets or sets a value indicating whether an upgrade is required.
             /// </summary>
             public bool RequiresUpgrade { get; set; }

@@ -625,7 +625,7 @@
             public bool Success { get; set; }

             /// <summary>
-            /// Gets or sets ... fixme
+            /// Gets or sets an install progress pseudo-percentage.
             /// </summary>
             public string Percentage { get; set; }
         }