Added OnDemandClientChannel receive tests

--- src/Lime.Protocol.UnitTests/Client/OnDemandClientChannelTests.cs
+++ src/Lime.Protocol.UnitTests/Client/OnDemandClientChannelTests.cs
@@ -179,6 +179,19 @@
         }

         [Test]
+        [ExpectedException(typeof(ObjectDisposedException))]
+        public async Task SendMessageAsync_ChannelDispose_ThrowsObjectDisposed()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            var target = GetTarget();
+            target.Dispose();
+
+            // Act
+            await target.SendMessageAsync(message);
+        }
+
+        [Test]
         [ExpectedException(typeof(ApplicationException))]
         public async Task SendMessageAsync_ChannelCreationFailedAndNotHandled_ThrowsException()
         {
@@ -221,9 +234,8 @@
                 }
             };
             _clientChannel
-                .SetupSequence(c => c.SendMessageAsync(message))
-                .Throws(exception)
-                .Returns(TaskUtil.CompletedTask);
+                .Setup(c => c.SendMessageAsync(message))
+                .Throws(exception);
             _establishedClientChannelBuilder
                 .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
                 .Returns(Task.FromResult(_clientChannel.Object))
@@ -729,5 +741,827 @@
             handlerArgs.IsConnected.ShouldBeTrue();
         }

+
+        [Test]
+        public async Task ReceiveMessageAsync_NotEstablishedChannel_BuildChannelAndReceives()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveMessageAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(message);
+            var target = GetTarget();
+
+            // Act
+            var actual = await target.ReceiveMessageAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(message);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Once());
+            _clientChannel.Verify(c => c.ReceiveMessageAsync(_cancellationToken), Times.Once());
+        }
+
+        [Test]
+        public async Task ReceiveMessageAsync_EstablishedChannel_ReceivesFromExistingChannel()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveMessageAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(message);
+            var target = GetTarget();
+            await target.ReceiveMessageAsync(_cancellationToken);
+            _establishedClientChannelBuilder.ResetCalls();
+            _clientChannel.ResetCalls();
+
+            // Act
+            var actual = await target.ReceiveMessageAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(message);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Never());
+            _clientChannel.Verify(c => c.ReceiveMessageAsync(_cancellationToken), Times.Once());
+        }
+
+        [Test]
+        public async Task ReceiveMessageAsync_ChannelCreationFailed_RecreateChannelAndReceives()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveMessageAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(message);
+            var target = GetTarget();
+            var exception = Dummy.CreateException();
+
+            object handlerSender = null;
+            ClientChannelExceptionEventArgs handlerArgs = null;
+            target.ChannelCreationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSender = sender;
+                    handlerArgs = args;
+                }
+            };
+
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception)
+                .Returns(Task.FromResult(_clientChannel.Object));
+
+            // Act
+            var actual = await target.ReceiveMessageAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(message);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(2));
+            _clientChannel.Verify(c => c.ReceiveMessageAsync(_cancellationToken), Times.Once());
+            handlerSender.ShouldNotBeNull();
+            handlerSender.ShouldBe(target);
+            handlerArgs.Exception.ShouldBe(exception);
+            handlerArgs.IsConnected.ShouldBeFalse();
+        }
+
+        [Test]
+        public async Task ReceiveMessageAsync_ChannelCreationFailsMultipleTimes_TryRecreateChannelAndReceives()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveMessageAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(message);
+            var target = GetTarget();
+            var exception1 = Dummy.CreateException();
+            var exception2 = Dummy.CreateException();
+            var exception3 = Dummy.CreateException();
+            var handlerSenders = new List<object>();
+            var handlerArgs = new List<ClientChannelExceptionEventArgs>();
+            target.ChannelCreationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSenders.Add(sender);
+                    handlerArgs.Add(args);
+                }
+            };
+
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception1)
+                .Throws(exception2)
+                .Throws(exception3)
+                .Returns(Task.FromResult(_clientChannel.Object));
+
+            // Act
+            var actual = await target.ReceiveMessageAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(message);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(4));
+            _clientChannel.Verify(c => c.ReceiveMessageAsync(_cancellationToken), Times.Once());
+            handlerSenders.Count.ShouldBe(3);
+            handlerArgs.Count.ShouldBe(3);
+            handlerArgs.Any(h => h.IsConnected).ShouldBeFalse();
+            handlerArgs.Select(e => e.Exception).ShouldContain(exception1);
+            handlerArgs.Select(e => e.Exception).ShouldContain(exception2);
+            handlerArgs.Select(e => e.Exception).ShouldContain(exception3);
+            handlerSenders.All(h => h.Equals(target)).ShouldBeTrue();
+        }
+
+        [Test]
+        [ExpectedException(typeof(ObjectDisposedException))]
+        public async Task ReceiveMessageAsync_ChannelDispose_ThrowsObjectDisposed()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            var target = GetTarget();
+            target.Dispose();
+
+            // Act
+            var actual = await target.ReceiveMessageAsync(_cancellationToken);
+        }
+
+        [Test]
+        [ExpectedException(typeof(TaskCanceledException))]
+        public async Task ReceiveMessageAsync_CanceledToken_ThrowsTaskCanceledException()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveMessageAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(message);
+            var target = GetTarget();
+            var cts = new CancellationTokenSource();
+            cts.Cancel();
+
+            // Act
+            var actual = await target.ReceiveMessageAsync(cts.Token);
+        }
+
+        [Test]
+        [ExpectedException(typeof(ApplicationException))]
+        public async Task ReceiveMessageAsync_ChannelCreationFailedAndNotHandled_ThrowsException()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            var target = GetTarget();
+            var exception = Dummy.CreateException<ApplicationException>();
+            target.ChannelCreationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    args.IsHandled = false;
+                }
+            };
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception)
+                .Returns(Task.FromResult(_clientChannel.Object));
+
+            // Act
+            var actual = await target.ReceiveMessageAsync(_cancellationToken);
+        }
+
+        [Test]
+        public async Task ReceiveMessageAsync_ChannelOperationFailed_RecreateChannelAndReceives()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveMessageAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(message);
+            var target = GetTarget();
+            var exception = Dummy.CreateException();
+            var clientChannel2 = new Mock<IClientChannel>();
+            object handlerSender = null;
+            ClientChannelExceptionEventArgs handlerArgs = null;
+            target.ChannelOperationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSender = sender;
+                    handlerArgs = args;
+                }
+            };
+            _clientChannel
+                .Setup(c => c.ReceiveMessageAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception);
+            clientChannel2
+                .Setup(c => c.ReceiveMessageAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(message);
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Returns(Task.FromResult(_clientChannel.Object))
+                .Returns(Task.FromResult(clientChannel2.Object));
+
+            // Act
+            var actual = await target.ReceiveMessageAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(message);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(2));
+            _clientChannel.Verify(c => c.ReceiveMessageAsync(_cancellationToken), Times.Once());
+            clientChannel2.Verify(c => c.ReceiveMessageAsync(_cancellationToken), Times.Once());
+            handlerSender.ShouldNotBeNull();
+            handlerSender.ShouldBe(target);
+            handlerArgs.Exception.ShouldBe(exception);
+            handlerArgs.IsConnected.ShouldBeFalse();
+        }
+
+        [Test]
+        public async Task ReceiveMessageAsync_ChannelOperationFailedButStillValid_CallsReceiveAgain()
+        {
+            // Arrange
+            var message = Dummy.CreateMessage(Dummy.CreatePlainDocument());
+            var target = GetTarget();
+            var exception = Dummy.CreateException();
+            object handlerSender = null;
+            ClientChannelExceptionEventArgs handlerArgs = null;
+            target.ChannelOperationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSender = sender;
+                    handlerArgs = args;
+                }
+            };
+            _clientChannel
+                .SetupGet(c => c.State)
+                .Returns(SessionState.Established);
+            _transport
+                .SetupGet(t => t.IsConnected)
+                .Returns(true);
+            _clientChannel
+                .SetupSequence(c => c.ReceiveMessageAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception)
+                .Returns(Task.FromResult(message));
+
+            // Act
+            var actual = await target.ReceiveMessageAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(message);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(1));
+            _clientChannel.Verify(c => c.ReceiveMessageAsync(_cancellationToken), Times.Exactly(2));
+            handlerSender.ShouldNotBeNull();
+            handlerSender.ShouldBe(target);
+            handlerArgs.Exception.ShouldBe(exception);
+            handlerArgs.IsConnected.ShouldBeTrue();
+        }
+
+        [Test]
+        public async Task ReceiveNotificationAsync_NotEstablishedChannel_BuildChannelAndReceives()
+        {
+            // Arrange
+            var notification = Dummy.CreateNotification(Event.Consumed);
+            _clientChannel
+                .Setup(c => c.ReceiveNotificationAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(notification);
+            var target = GetTarget();
+
+            // Act
+            var actual = await target.ReceiveNotificationAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(notification);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Once());
+            _clientChannel.Verify(c => c.ReceiveNotificationAsync(_cancellationToken), Times.Once());
+        }
+
+        [Test]
+        public async Task ReceiveNotificationAsync_EstablishedChannel_ReceivesFromExistingChannel()
+        {
+            // Arrange
+            var notification = Dummy.CreateNotification(Event.Consumed);
+            _clientChannel
+                .Setup(c => c.ReceiveNotificationAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(notification);
+            var target = GetTarget();
+            await target.ReceiveNotificationAsync(_cancellationToken);
+            _establishedClientChannelBuilder.ResetCalls();
+            _clientChannel.ResetCalls();
+
+            // Act
+            var actual = await target.ReceiveNotificationAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(notification);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Never());
+            _clientChannel.Verify(c => c.ReceiveNotificationAsync(_cancellationToken), Times.Once());
+        }
+
+        [Test]
+        public async Task ReceiveNotificationAsync_ChannelCreationFailed_RecreateChannelAndReceives()
+        {
+            // Arrange
+            var notification = Dummy.CreateNotification(Event.Consumed);
+            _clientChannel
+                .Setup(c => c.ReceiveNotificationAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(notification);
+            var target = GetTarget();
+            var exception = Dummy.CreateException();
+
+            object handlerSender = null;
+            ClientChannelExceptionEventArgs handlerArgs = null;
+            target.ChannelCreationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSender = sender;
+                    handlerArgs = args;
+                }
+            };
+
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception)
+                .Returns(Task.FromResult(_clientChannel.Object));
+
+            // Act
+            var actual = await target.ReceiveNotificationAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(notification);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(2));
+            _clientChannel.Verify(c => c.ReceiveNotificationAsync(_cancellationToken), Times.Once());
+            handlerSender.ShouldNotBeNull();
+            handlerSender.ShouldBe(target);
+            handlerArgs.Exception.ShouldBe(exception);
+            handlerArgs.IsConnected.ShouldBeFalse();
+        }
+
+        [Test]
+        public async Task ReceiveNotificationAsync_ChannelCreationFailsMultipleTimes_TryRecreateChannelAndReceives()
+        {
+            // Arrange
+            var notification = Dummy.CreateNotification(Event.Consumed);
+            _clientChannel
+                .Setup(c => c.ReceiveNotificationAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(notification);
+            var target = GetTarget();
+            var exception1 = Dummy.CreateException();
+            var exception2 = Dummy.CreateException();
+            var exception3 = Dummy.CreateException();
+            var handlerSenders = new List<object>();
+            var handlerArgs = new List<ClientChannelExceptionEventArgs>();
+            target.ChannelCreationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSenders.Add(sender);
+                    handlerArgs.Add(args);
+                }
+            };
+
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception1)
+                .Throws(exception2)
+                .Throws(exception3)
+                .Returns(Task.FromResult(_clientChannel.Object));
+
+            // Act
+            var actual = await target.ReceiveNotificationAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(notification);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(4));
+            _clientChannel.Verify(c => c.ReceiveNotificationAsync(_cancellationToken), Times.Once());
+            handlerSenders.Count.ShouldBe(3);
+            handlerArgs.Count.ShouldBe(3);
+            handlerArgs.Any(h => h.IsConnected).ShouldBeFalse();
+            handlerArgs.Select(e => e.Exception).ShouldContain(exception1);
+            handlerArgs.Select(e => e.Exception).ShouldContain(exception2);
+            handlerArgs.Select(e => e.Exception).ShouldContain(exception3);
+            handlerSenders.All(h => h.Equals(target)).ShouldBeTrue();
+        }
+
+        [Test]
+        [ExpectedException(typeof(ObjectDisposedException))]
+        public async Task ReceiveNotificationAsync_ChannelDispose_ThrowsObjectDisposed()
+        {
+            // Arrange
+            var notification = Dummy.CreateNotification(Event.Consumed);
+            var target = GetTarget();
+            target.Dispose();
+
+            // Act
+            var actual = await target.ReceiveNotificationAsync(_cancellationToken);
+        }
+
+        [Test]
+        [ExpectedException(typeof(TaskCanceledException))]
+        public async Task ReceiveNotificationAsync_CanceledToken_ThrowsTaskCanceledException()
+        {
+            // Arrange
+            var notification = Dummy.CreateNotification(Event.Consumed);
+            _clientChannel
+                .Setup(c => c.ReceiveNotificationAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(notification);
+            var target = GetTarget();
+            var cts = new CancellationTokenSource();
+            cts.Cancel();
+
+            // Act
+            var actual = await target.ReceiveNotificationAsync(cts.Token);
+        }
+
+        [Test]
+        [ExpectedException(typeof(ApplicationException))]
+        public async Task ReceiveNotificationAsync_ChannelCreationFailedAndNotHandled_ThrowsException()
+        {
+            // Arrange
+            var notification = Dummy.CreateNotification(Event.Consumed);
+            var target = GetTarget();
+            var exception = Dummy.CreateException<ApplicationException>();
+            target.ChannelCreationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    args.IsHandled = false;
+                }
+            };
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception)
+                .Returns(Task.FromResult(_clientChannel.Object));
+
+            // Act
+            var actual = await target.ReceiveNotificationAsync(_cancellationToken);
+        }
+
+        [Test]
+        public async Task ReceiveNotificationAsync_ChannelOperationFailed_RecreateChannelAndReceives()
+        {
+            // Arrange
+            var notification = Dummy.CreateNotification(Event.Consumed);
+            _clientChannel
+                .Setup(c => c.ReceiveNotificationAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(notification);
+            var target = GetTarget();
+            var exception = Dummy.CreateException();
+            var clientChannel2 = new Mock<IClientChannel>();
+            object handlerSender = null;
+            ClientChannelExceptionEventArgs handlerArgs = null;
+            target.ChannelOperationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSender = sender;
+                    handlerArgs = args;
+                }
+            };
+            _clientChannel
+                .Setup(c => c.ReceiveNotificationAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception);
+            clientChannel2
+                .Setup(c => c.ReceiveNotificationAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(notification);
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Returns(Task.FromResult(_clientChannel.Object))
+                .Returns(Task.FromResult(clientChannel2.Object));
+
+            // Act
+            var actual = await target.ReceiveNotificationAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(notification);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(2));
+            _clientChannel.Verify(c => c.ReceiveNotificationAsync(_cancellationToken), Times.Once());
+            clientChannel2.Verify(c => c.ReceiveNotificationAsync(_cancellationToken), Times.Once());
+            handlerSender.ShouldNotBeNull();
+            handlerSender.ShouldBe(target);
+            handlerArgs.Exception.ShouldBe(exception);
+            handlerArgs.IsConnected.ShouldBeFalse();
+        }
+
+        [Test]
+        public async Task ReceiveNotificationAsync_ChannelOperationFailedButStillValid_CallsReceiveAgain()
+        {
+            // Arrange
+            var notification = Dummy.CreateNotification(Event.Consumed);
+            var target = GetTarget();
+            var exception = Dummy.CreateException();
+            object handlerSender = null;
+            ClientChannelExceptionEventArgs handlerArgs = null;
+            target.ChannelOperationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSender = sender;
+                    handlerArgs = args;
+                }
+            };
+            _clientChannel
+                .SetupGet(c => c.State)
+                .Returns(SessionState.Established);
+            _transport
+                .SetupGet(t => t.IsConnected)
+                .Returns(true);
+            _clientChannel
+                .SetupSequence(c => c.ReceiveNotificationAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception)
+                .Returns(Task.FromResult(notification));
+
+            // Act
+            var actual = await target.ReceiveNotificationAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(notification);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(1));
+            _clientChannel.Verify(c => c.ReceiveNotificationAsync(_cancellationToken), Times.Exactly(2));
+            handlerSender.ShouldNotBeNull();
+            handlerSender.ShouldBe(target);
+            handlerArgs.Exception.ShouldBe(exception);
+            handlerArgs.IsConnected.ShouldBeTrue();
+        }
+
+        [Test]
+        public async Task ReceiveCommandAsync_NotEstablishedChannel_BuildChannelAndReceives()
+        {
+            // Arrange
+            var command = Dummy.CreateCommand(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveCommandAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(command);
+            var target = GetTarget();
+
+            // Act
+            var actual = await target.ReceiveCommandAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(command);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Once());
+            _clientChannel.Verify(c => c.ReceiveCommandAsync(_cancellationToken), Times.Once());
+        }
+
+        [Test]
+        public async Task ReceiveCommandAsync_EstablishedChannel_ReceivesFromExistingChannel()
+        {
+            // Arrange
+            var command = Dummy.CreateCommand(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveCommandAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(command);
+            var target = GetTarget();
+            await target.ReceiveCommandAsync(_cancellationToken);
+            _establishedClientChannelBuilder.ResetCalls();
+            _clientChannel.ResetCalls();
+
+            // Act
+            var actual = await target.ReceiveCommandAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(command);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Never());
+            _clientChannel.Verify(c => c.ReceiveCommandAsync(_cancellationToken), Times.Once());
+        }
+
+        [Test]
+        public async Task ReceiveCommandAsync_ChannelCreationFailed_RecreateChannelAndReceives()
+        {
+            // Arrange
+            var command = Dummy.CreateCommand(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveCommandAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(command);
+            var target = GetTarget();
+            var exception = Dummy.CreateException();
+
+            object handlerSender = null;
+            ClientChannelExceptionEventArgs handlerArgs = null;
+            target.ChannelCreationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSender = sender;
+                    handlerArgs = args;
+                }
+            };
+
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception)
+                .Returns(Task.FromResult(_clientChannel.Object));
+
+            // Act
+            var actual = await target.ReceiveCommandAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(command);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(2));
+            _clientChannel.Verify(c => c.ReceiveCommandAsync(_cancellationToken), Times.Once());
+            handlerSender.ShouldNotBeNull();
+            handlerSender.ShouldBe(target);
+            handlerArgs.Exception.ShouldBe(exception);
+            handlerArgs.IsConnected.ShouldBeFalse();
+        }
+
+        [Test]
+        public async Task ReceiveCommandAsync_ChannelCreationFailsMultipleTimes_TryRecreateChannelAndReceives()
+        {
+            // Arrange
+            var command = Dummy.CreateCommand(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveCommandAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(command);
+            var target = GetTarget();
+            var exception1 = Dummy.CreateException();
+            var exception2 = Dummy.CreateException();
+            var exception3 = Dummy.CreateException();
+            var handlerSenders = new List<object>();
+            var handlerArgs = new List<ClientChannelExceptionEventArgs>();
+            target.ChannelCreationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSenders.Add(sender);
+                    handlerArgs.Add(args);
+                }
+            };
+
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception1)
+                .Throws(exception2)
+                .Throws(exception3)
+                .Returns(Task.FromResult(_clientChannel.Object));
+
+            // Act
+            var actual = await target.ReceiveCommandAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(command);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(4));
+            _clientChannel.Verify(c => c.ReceiveCommandAsync(_cancellationToken), Times.Once());
+            handlerSenders.Count.ShouldBe(3);
+            handlerArgs.Count.ShouldBe(3);
+            handlerArgs.Any(h => h.IsConnected).ShouldBeFalse();
+            handlerArgs.Select(e => e.Exception).ShouldContain(exception1);
+            handlerArgs.Select(e => e.Exception).ShouldContain(exception2);
+            handlerArgs.Select(e => e.Exception).ShouldContain(exception3);
+            handlerSenders.All(h => h.Equals(target)).ShouldBeTrue();
+        }
+
+        [Test]
+        [ExpectedException(typeof(ObjectDisposedException))]
+        public async Task ReceiveCommandAsync_ChannelDispose_ThrowsObjectDisposed()
+        {
+            // Arrange
+            var command = Dummy.CreateCommand(Dummy.CreatePlainDocument());
+            var target = GetTarget();
+            target.Dispose();
+
+            // Act
+            var actual = await target.ReceiveCommandAsync(_cancellationToken);
+        }
+
+        [Test]
+        [ExpectedException(typeof(TaskCanceledException))]
+        public async Task ReceiveCommandAsync_CanceledToken_ThrowsTaskCanceledException()
+        {
+            // Arrange
+            var command = Dummy.CreateCommand(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveCommandAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(command);
+            var target = GetTarget();
+            var cts = new CancellationTokenSource();
+            cts.Cancel();
+
+            // Act
+            var actual = await target.ReceiveCommandAsync(cts.Token);
+        }
+
+        [Test]
+        [ExpectedException(typeof(ApplicationException))]
+        public async Task ReceiveCommandAsync_ChannelCreationFailedAndNotHandled_ThrowsException()
+        {
+            // Arrange
+            var command = Dummy.CreateCommand(Dummy.CreatePlainDocument());
+            var target = GetTarget();
+            var exception = Dummy.CreateException<ApplicationException>();
+            target.ChannelCreationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    args.IsHandled = false;
+                }
+            };
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception)
+                .Returns(Task.FromResult(_clientChannel.Object));
+
+            // Act
+            var actual = await target.ReceiveCommandAsync(_cancellationToken);
+        }
+
+        [Test]
+        public async Task ReceiveCommandAsync_ChannelOperationFailed_RecreateChannelAndReceives()
+        {
+            // Arrange
+            var command = Dummy.CreateCommand(Dummy.CreatePlainDocument());
+            _clientChannel
+                .Setup(c => c.ReceiveCommandAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(command);
+            var target = GetTarget();
+            var exception = Dummy.CreateException();
+            var clientChannel2 = new Mock<IClientChannel>();
+            object handlerSender = null;
+            ClientChannelExceptionEventArgs handlerArgs = null;
+            target.ChannelOperationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSender = sender;
+                    handlerArgs = args;
+                }
+            };
+            _clientChannel
+                .Setup(c => c.ReceiveCommandAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception);
+            clientChannel2
+                .Setup(c => c.ReceiveCommandAsync(It.IsAny<CancellationToken>()))
+                .ReturnsAsync(command);
+            _establishedClientChannelBuilder
+                .SetupSequence(b => b.BuildAndEstablishAsync(It.IsAny<CancellationToken>()))
+                .Returns(Task.FromResult(_clientChannel.Object))
+                .Returns(Task.FromResult(clientChannel2.Object));
+
+            // Act
+            var actual = await target.ReceiveCommandAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(command);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(2));
+            _clientChannel.Verify(c => c.ReceiveCommandAsync(_cancellationToken), Times.Once());
+            clientChannel2.Verify(c => c.ReceiveCommandAsync(_cancellationToken), Times.Once());
+            handlerSender.ShouldNotBeNull();
+            handlerSender.ShouldBe(target);
+            handlerArgs.Exception.ShouldBe(exception);
+            handlerArgs.IsConnected.ShouldBeFalse();
+        }
+
+        [Test]
+        public async Task ReceiveCommandAsync_ChannelOperationFailedButStillValid_CallsReceiveAgain()
+        {
+            // Arrange
+            var command = Dummy.CreateCommand(Dummy.CreatePlainDocument());
+            var target = GetTarget();
+            var exception = Dummy.CreateException();
+            object handlerSender = null;
+            ClientChannelExceptionEventArgs handlerArgs = null;
+            target.ChannelOperationFailed += (sender, args) =>
+            {
+                using (args.GetDeferral())
+                {
+                    handlerSender = sender;
+                    handlerArgs = args;
+                }
+            };
+            _clientChannel
+                .SetupGet(c => c.State)
+                .Returns(SessionState.Established);
+            _transport
+                .SetupGet(t => t.IsConnected)
+                .Returns(true);
+            _clientChannel
+                .SetupSequence(c => c.ReceiveCommandAsync(It.IsAny<CancellationToken>()))
+                .Throws(exception)
+                .Returns(Task.FromResult(command));
+
+            // Act
+            var actual = await target.ReceiveCommandAsync(_cancellationToken);
+
+            // Assert
+            actual.ShouldBe(command);
+            _establishedClientChannelBuilder.Verify(c => c.BuildAndEstablishAsync(It.IsAny<CancellationToken>()),
+                Times.Exactly(1));
+            _clientChannel.Verify(c => c.ReceiveCommandAsync(_cancellationToken), Times.Exactly(2));
+            handlerSender.ShouldNotBeNull();
+            handlerSender.ShouldBe(target);
+            handlerArgs.Exception.ShouldBe(exception);
+            handlerArgs.IsConnected.ShouldBeTrue();
+        }
     }
 }


Removed ctr

Removed ctr

--- src/MICCookBook/MICCookBook.Web/Controllers/RecipesController.cs
+++ src/MICCookBook/MICCookBook.Web/Controllers/RecipesController.cs
@@ -11,11 +11,6 @@
 {
     public class RecipesController : BaseController
     {
-        public RecipesController()
-        {
-
-        }
-
         // GET: Recipes
         public async Task<ActionResult> Index()
         {


QuartzIntegrationExtensions.UseInMemoryScheduler overload with ISchedulerFactory parameter

--- src/MassTransit.QuartzIntegration/QuartzIntegrationExtensions.cs
+++ src/MassTransit.QuartzIntegration/QuartzIntegrationExtensions.cs
@@ -30,6 +30,17 @@
                 throw new ArgumentNullException(nameof(configurator));

             ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
+            return configurator.UseInMemoryScheduler(schedulerFactory, queueName);
+        }
+
+        public static Uri UseInMemoryScheduler(this IBusFactoryConfigurator configurator, ISchedulerFactory schedulerFactory, string queueName = "quartz")
+        {
+            if (configurator == null)
+                throw new ArgumentNullException(nameof(configurator));
+
+            if (schedulerFactory == null)
+                throw new ArgumentNullException(nameof(schedulerFactory));
+
             var scheduler = TaskUtil.Await(() => schedulerFactory.GetScheduler());

             Uri inputAddress = null;


* MonoTorrent/MonoTorrent.Client/Managers/ConnectionManager.cs: Fix
  a math overflow error. Thanks to nivanov.

svn path=/trunk/bitsharp/; revision=153792

--- src/MonoTorrent/MonoTorrent.Client/Managers/ConnectionManager.cs
+++ src/MonoTorrent/MonoTorrent.Client/Managers/ConnectionManager.cs
@@ -605,7 +605,7 @@
                     PieceMessage pm = (PieceMessage)msg;
                     pm.Data = BufferManager.EmptyBuffer;
                     ClientEngine.BufferManager.GetBuffer(ref pm.Data, pm.ByteLength);
-                    engine.DiskManager.QueueRead(id.TorrentManager, pm.StartOffset + (pm.PieceIndex * id.TorrentManager.Torrent.PieceLength), pm.Data, pm.RequestLength, delegate
+                    engine.DiskManager.QueueRead(id.TorrentManager, pm.StartOffset + ((long) pm.PieceIndex * id.TorrentManager.Torrent.PieceLength), pm.Data, pm.RequestLength, delegate
                     {
                         handle.Set();
                     });


documentation improvement

documentation improvement

--- src/NUnitFramework/framework/Constraints/ComparisonConstraint.cs
+++ src/NUnitFramework/framework/Constraints/ComparisonConstraint.cs
@@ -155,7 +155,7 @@
         /// Provides standard description of what the constraint tests
         /// based on comparison text.
         /// </summary>
-        /// <param name="comparisonText">Describes, what constraint tests, throws <see cref="ArgumentNullException"/>
+        /// <param name="comparisonText">Describes the comparison being tested, throws <see cref="ArgumentNullException"/>
         /// if null</param>
         /// <exception cref="ArgumentNullException">Is thrown when null passed to a method</exception>
         protected string DefaultDescription(string comparisonText)


Change to use ConcurrentQueue.IsEmpty instead of ConcurrentQueue.Count

--- src/NUnitFramework/framework/Internal/Results/TestSuiteResult.cs
+++ src/NUnitFramework/framework/Internal/Results/TestSuiteResult.cs
@@ -95,7 +95,7 @@
         /// </summary>
         public override bool HasChildren
         {
-            get { return _children.Count > 0; }
+            get { return !_children.IsEmpty; }
         }

         /// <summary>


2144.22

--- src/PixelFarm/PixelFarm.Drawing/9_BitmapAtlas/BitmapAtlasFile.cs
+++ src/PixelFarm/PixelFarm.Drawing/9_BitmapAtlas/BitmapAtlasFile.cs
@@ -90,7 +90,7 @@
             {
                 //read each glyph map info

-                var item = new AtlasItem(reader.ReadUInt16());
+                var item = new AtlasItem(reader.ReadUInt16());

                 //2. area
                 item.Left = reader.ReadUInt16();
@@ -247,10 +247,10 @@
             //
             foreach (var kp in items)
             {
-                ushort glyphIndex = kp.Key;
+                ushort uniqueName = kp.Key;
                 AtlasItem g = kp.Value;
-                //1. glyph index
-                _writer.Write((ushort)glyphIndex);
+                //1. unique uint16 name
+                _writer.Write((ushort)uniqueName);

                 //2. area, left,top,width,height
                 _writer.Write((ushort)g.Left);


Refactored test

Refactored test

--- src/Tests/Hadouken.UnitTests/BitTorrent/BitTorrentEngineTests.cs
+++ src/Tests/Hadouken.UnitTests/BitTorrent/BitTorrentEngineTests.cs
@@ -1,81 +1,73 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using NUnit.Framework;
-using Hadouken.Impl.BitTorrent;
-using Moq;
-using Hadouken.IO;
-using Hadouken.Messaging;
-using Hadouken.Data;
-using Hadouken.Data.Models;
-using Hadouken.Configuration;
-
-namespace Hadouken.UnitTests.BitTorrent
-{
-    [TestFixture]
-    public class BitTorrentEngineTests
-    {
-        [Test]
-        public void Does_not_care_about_null_data()
-        {
-            var fs = new Mock<IFileSystem>();
-            var bus = new Mock<IMessageBus>();
-            var repo = new Mock<IDataRepository>();
-            var kvs = new Mock<IKeyValueStore>();
-
-            repo.Setup(r => r.List<TorrentInfo>()).Returns(new List<TorrentInfo>());
-
-            var engine = new MonoTorrentEngine(fs.Object, bus.Object, repo.Object, kvs.Object);
-            engine.Load();
-
-            var t = engine.AddTorrent(null);
-
-            Assert.IsNull(t);
-        }
-
-        [Test]
-        public void Does_not_care_about_garbage_data()
-        {
-            var fs = new Mock<IFileSystem>();
-            var bus = new Mock<IMessageBus>();
-            var repo = new Mock<IDataRepository>();
-            var kvs = new Mock<IKeyValueStore>();
-
-            repo.Setup(r => r.List<TorrentInfo>()).Returns(new List<TorrentInfo>());
-
-            var engine = new MonoTorrentEngine(fs.Object, bus.Object, repo.Object, kvs.Object);
-            engine.Load();
-
-            var t = engine.AddTorrent(new byte[] { 6, 7, 1, 4, 5, 3, 3 }); // garbage data :)
-
-            Assert.IsNull(t);
-        }
-
-        [Test]
-        public void Can_load_and_unload_torrent()
-        {
-            var fs = new Mock<IFileSystem>();
-            var bus = new Mock<IMessageBus>();
-            var repo = new Mock<IDataRepository>();
-            var kvs = new Mock<IKeyValueStore>();
-
-            repo.Setup(r => r.List<TorrentInfo>()).Returns(new List<TorrentInfo>());
-
-            byte[] torrent = TestHelper.LoadResource("Hadouken.UnitTests.Resources.ubuntu.torrent").ToArray();
-
-            var engine = new MonoTorrentEngine(fs.Object, bus.Object, repo.Object, kvs.Object);
-            engine.Load();
-
-            var manager = engine.AddTorrent(torrent, "/temp");
-
-            Assert.IsNotNull(manager);
-            Assert.IsTrue(engine.Managers.ContainsKey(manager.InfoHash));
-
-            engine.RemoveTorrent(manager);
-
-            Assert.IsFalse(engine.Managers.ContainsKey(manager.InfoHash));
-        }
-    }
-}
+using System.Collections.Generic;
+using NUnit.Framework;
+using Hadouken.Impl.BitTorrent;
+using Moq;
+using Hadouken.IO;
+using Hadouken.Messaging;
+using Hadouken.Data;
+using Hadouken.Data.Models;
+using Hadouken.Configuration;
+
+namespace Hadouken.UnitTests.BitTorrent
+{
+    [TestFixture]
+    public class BitTorrentEngineTests
+    {
+        private readonly Mock<IFileSystem> fs = new Mock<IFileSystem>();
+        private readonly Mock<IMessageBus> bus = new Mock<IMessageBus>();
+        private readonly Mock<IDataRepository> repo = new Mock<IDataRepository>();
+        private readonly Mock<IKeyValueStore> kvs = new Mock<IKeyValueStore>();
+        private MonoTorrentEngine engine;
+
+        [SetUp]
+        public void SetUp()
+        {
+            engine = new MonoTorrentEngine(fs.Object, bus.Object, repo.Object, kvs.Object);
+        }
+
+        [TearDown]
+        public void TearDown()
+        {
+            engine = null;
+        }
+
+        [Test]
+        public void Does_not_care_about_null_data()
+        {
+            repo.Setup(r => r.List<TorrentInfo>()).Returns(new List<TorrentInfo>());
+
+            engine.Load();
+            var t = engine.AddTorrent(null);
+
+            Assert.IsNull(t);
+        }
+
+        [Test]
+        public void Does_not_care_about_garbage_data()
+        {
+            repo.Setup(r => r.List<TorrentInfo>()).Returns(new List<TorrentInfo>());
+
+            engine.Load();
+            var t = engine.AddTorrent(new byte[] { 6, 7, 1, 4, 5, 3, 3 }); // garbage data :)
+
+            Assert.IsNull(t);
+        }
+
+        [Test]
+        public void Can_load_and_unload_torrent()
+        {
+            repo.Setup(r => r.List<TorrentInfo>()).Returns(new List<TorrentInfo>());
+            byte[] torrent = TestHelper.LoadResource("Hadouken.UnitTests.Resources.ubuntu.torrent").ToArray();
+
+            engine.Load();
+            var manager = engine.AddTorrent(torrent, "/temp");
+
+            Assert.IsNotNull(manager);
+            Assert.IsTrue(engine.Managers.ContainsKey(manager.InfoHash));
+
+            engine.RemoveTorrent(manager);
+
+            Assert.IsFalse(engine.Managers.ContainsKey(manager.InfoHash));
+        }
+    }
+}


Skip top hits repro tests for ES < 1.3

Skip top hits repro tests for ES < 1.3

--- src/Tests/Nest.Tests.Integration/Reproduce/Reproduce1169Tests.cs
+++ src/Tests/Nest.Tests.Integration/Reproduce/Reproduce1169Tests.cs
@@ -13,6 +13,7 @@
 	public class Reproduce1169Tests : IntegrationTests
 	{
 		[Test]
+		[SkipVersion("0 - 1.2.9", "Top hits agg added in 1.3")]
 		public void TopHitsReturnedFirst()
 		{
 			var response = this.Client.Search<ElasticsearchProject>(s => s
@@ -39,6 +40,7 @@
 		}

 		[Test]
+		[SkipVersion("0 - 1.2.9", "Top hits agg added in 1.3")]
 		public void TermsReturnedFirst()
 		{
 			var response = this.Client.Search<ElasticsearchProject>(s => s


Improve performance of FindNodeByMoniker

* Don't recurse in non-parent paths

--- src/VsChromium/Features/SourceExplorerHierarchy/NodeViewModel.cs
+++ src/VsChromium/Features/SourceExplorerHierarchy/NodeViewModel.cs
@@ -2,14 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.

+using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.Shell.Interop;
 using System;
 using System.Collections.Generic;
-using System.Diagnostics;
 using System.Drawing;
-using System.IO;
 using System.Text;
-using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.Shell.Interop;
 using VsChromium.Core.Files;
 using VsChromium.Core.Logging;

@@ -34,37 +32,17 @@
     public bool IsExpanded { get; set; }
     public NodeViewModelTemplate Template { get; set; }

-    public int ImageIndex {
-      get { return Template.ImageIndex; }
-    }
-    public int OpenFolderImageIndex {
-      get { return Template.OpenFolderImageIndex; }
-    }
-    public Icon Icon {
-      get { return Template.Icon; }
-    }
-    public Icon OpenFolderIcon {
-      get { return Template.OpenFolderIcon; }
-    }
-    public bool ExpandByDefault {
-      get { return Template.ExpandByDefault; }
-    }
-
-    public bool IsRoot {
-      get {
-        return ItemId == VsHierarchyNodes.RootNodeItemId;
-      }
-    }
-
-    protected abstract IList<NodeViewModel> ChildrenImpl { get; }
-
-    public IList<NodeViewModel> Children {
-      get { return ChildrenImpl; }
-    }
-
-    public NodeViewModel Parent {
-      get { return _parent; }
-    }
+    public int ImageIndex => Template.ImageIndex;
+    public int OpenFolderImageIndex => Template.OpenFolderImageIndex;
+    public Icon Icon => Template.Icon;
+    public Icon OpenFolderIcon => Template.OpenFolderIcon;
+    public bool ExpandByDefault => Template.ExpandByDefault;
+    public bool IsRoot => ItemId == VsHierarchyNodes.RootNodeItemId;
+
+
+    public IList<NodeViewModel> Children => ChildrenImpl;
+
+    public NodeViewModel Parent => _parent;

     public string FullPath {
       get {
@@ -74,6 +52,9 @@
       }
     }

+
+    public FullPath Path => new FullPath(FullPath);
+
     public string RelativePath {
       get {
         var sb = new StringBuilder(260);
@@ -82,42 +63,6 @@
       }
     }

-    private void AppendFullPath(StringBuilder sb) {
-      if (string.IsNullOrEmpty(this.Name))
-        return;
-
-      if (PathHelpers.IsAbsolutePath(this.Name)) {
-        sb.Append(this.Name);
-        return;
-      }
-
-      if (_parent == null)
-        return;
-
-      _parent.AppendFullPath(sb);
-      if (sb.Length > 0) {
-        sb.Append(Path.DirectorySeparatorChar);
-      }
-      sb.Append(this.Name);
-    }
-
-    private void AppendRelativePath(StringBuilder sb) {
-      if (string.IsNullOrEmpty(this.Name))
-        return;
-
-      if (PathHelpers.IsAbsolutePath(this.Name))
-        return;
-
-      if (_parent == null)
-        return;
-
-      _parent.AppendRelativePath(sb);
-      if (sb.Length > 0) {
-        sb.Append(Path.DirectorySeparatorChar);
-      }
-      sb.Append(this.Name);
-    }
-
     public uint GetFirstChildItemId() {
       if (ChildrenImpl.Count == 0)
         return VSConstants.VSITEMID_NIL;
@@ -160,59 +105,23 @@
       ChildrenImpl.Add(node);
     }

-    private IntPtr GetIconHandleForImageIndex(int imageIndex) {
-      return IntPtr.Zero;
-    }
-
-    private IntPtr GetIconHandle() {
-      var icon = this.Icon;
-      if (icon != null)
-        return icon.Handle;
-      return GetIconHandleForImageIndex(GetImageIndex());
-    }
-
-    private IntPtr GetOpenFolderIconHandle() {
-      var icon = OpenFolderIcon;
-      if (Icon != null && icon != null)
-        return icon.Handle;
-      return GetIconHandleForImageIndex(GetOpenFolderImageIndex());
-    }
-
     public int GetChildrenCount() {
       return ChildrenImpl.Count;
     }

-    private int GetImageIndex() {
-      return ImageIndex;
-    }
-
-    private int GetOpenFolderImageIndex() {
-      return OpenFolderImageIndex;
-    }
-
-    private bool FindNodeByMonikerHelper(NodeViewModel parentNode, string searchMoniker, out NodeViewModel foundNode) {
-      foundNode = null;
-      if (parentNode == null)
-        return false;
-
-      if (SystemPathComparer.Instance.StringComparer.Equals(parentNode.FullPath, searchMoniker)) {
-        foundNode = parentNode;
-        return true;
-      }
-
-      foreach (var child in parentNode.ChildrenImpl) {
-        if (FindNodeByMonikerHelper(child, searchMoniker, out foundNode)) {
-          return true;
-        }
-      }
-      return false;
-    }
-
     public bool FindNodeByMoniker(string searchMoniker, out NodeViewModel node) {
       node = null;
-      if (!IsRoot)
+      if (!IsRoot) {
         return false;
-      return FindNodeByMonikerHelper(this, searchMoniker, out node);
+      }
+
+      FullPath path;
+      try {
+        path = new FullPath(searchMoniker);
+      } catch (Exception) {
+        return false;
+      }
+      return FindNodeByMonikerHelper(this, path, out node);
     }

     public string GetMkDocument() {
@@ -246,7 +155,7 @@
           pvar = GetFirstChildItemId();
           break;
         case (int)__VSHPROPID.VSHPROPID_Expanded:
-          pvar = (this.IsExpanded ? 1 : 0);
+          pvar = (IsExpanded ? 1 : 0);
           break;
         case (int)__VSHPROPID.VSHPROPID_ItemDocCookie:
           pvar = ItemId;
@@ -306,5 +215,94 @@
       }
       return VSConstants.S_OK;
     }
+
+    protected abstract IList<NodeViewModel> ChildrenImpl { get; }
+
+    private void AppendFullPath(StringBuilder sb) {
+      if (string.IsNullOrEmpty(Name))
+        return;
+
+      if (PathHelpers.IsAbsolutePath(Name)) {
+        sb.Append(Name);
+        return;
+      }
+
+      if (_parent == null)
+        return;
+
+      _parent.AppendFullPath(sb);
+      if (sb.Length > 0) {
+        sb.Append(System.IO.Path.DirectorySeparatorChar);
+      }
+      sb.Append(Name);
+    }
+
+    private void AppendRelativePath(StringBuilder sb) {
+      if (string.IsNullOrEmpty(Name))
+        return;
+
+      if (PathHelpers.IsAbsolutePath(Name))
+        return;
+
+      if (_parent == null)
+        return;
+
+      _parent.AppendRelativePath(sb);
+      if (sb.Length > 0) {
+        sb.Append(System.IO.Path.DirectorySeparatorChar);
+      }
+      sb.Append(Name);
+    }
+
+    private IntPtr GetIconHandleForImageIndex() {
+      return IntPtr.Zero;
+    }
+
+    private IntPtr GetIconHandle() {
+      var icon = Icon;
+      if (icon != null)
+        return icon.Handle;
+      return GetIconHandleForImageIndex();
+    }
+
+    private IntPtr GetOpenFolderIconHandle() {
+      var icon = OpenFolderIcon;
+      if (Icon != null && icon != null)
+        return icon.Handle;
+      return GetIconHandleForImageIndex();
+    }
+
+    private int GetImageIndex() {
+      return ImageIndex;
+    }
+
+    private int GetOpenFolderImageIndex() {
+      return OpenFolderImageIndex;
+    }
+
+    private bool FindNodeByMonikerHelper(NodeViewModel node, FullPath path, out NodeViewModel foundNode) {
+      var nodePath = node.Path;
+
+      // Path found?
+      if (nodePath.Equals(path)) {
+        foundNode = node;
+        return true;
+      }
+
+      // If node is not a parent, bail out
+      if (!nodePath.ContainsPath(path)) {
+        foundNode = null;
+        return false;
+      }
+
+      // Examine children nodes
+      foreach (var child in node.ChildrenImpl) {
+        if (FindNodeByMonikerHelper(child, path, out foundNode)) {
+          return true;
+        }
+      }
+      foundNode = null;
+      return false;
+    }
   }
 }


Signed-off-by: 桐铭 梁 <497562602@163.com>

Signed-off-by: 桐铭 梁 <497562602@163.com>

--- src/YoYoCms.AbpProjectTemplate.Web/Controllers/HomeController.cs
+++ src/YoYoCms.AbpProjectTemplate.Web/Controllers/HomeController.cs
@@ -11,11 +11,11 @@
         }

         /// <summary>
-        /// 前端项目首页
+        /// 管理端Vue项目首页
         /// </summary>
         /// <returns></returns>
         public ActionResult ForntProj ()
-        {
+        {
             return File(System.IO.File.Open(Server.MapPath("/Assets/dist/index.html"), System.IO.FileMode.Open), "text/html");
         }
 	}


ScheduledJobsWorker

ScheduledJobsWorker

* added ActivityId if none is set
* added JobId to plugins via parameters

--- src/biz.dfch.CS.Appclusive.Scheduler.Core/ScheduledJobsWorker.cs
+++ src/biz.dfch.CS.Appclusive.Scheduler.Core/ScheduledJobsWorker.cs
@@ -207,22 +207,28 @@

                         var scheduledJobsManager = new ScheduledJobsManager(endpoints);
                         var parameters = scheduledJobsManager.ConvertJobParameters(job.Action, job.ScheduledJobParameters);
-
-                        Trace.WriteLine("Invoking {0} with plugin '{1}' ...", job.Id, job.Action);
+                        parameters.Add("JobId", job.Id);
+
+                        if(default(Guid) == System.Diagnostics.Trace.CorrelationManager.ActivityId)
+                        {
+                            System.Diagnostics.Trace.CorrelationManager.ActivityId = Guid.NewGuid();
+                        }
+
+                        Trace.WriteLine("Invoking {0} with plugin '{1}' [ActivityId {2}] ...", job.Id, job.Action, System.Diagnostics.Trace.CorrelationManager.ActivityId);
                         plugin.Value.Invoke(parameters, invocationResult);

                         if(invocationResult.Succeeded)
                         {
-                            Trace.WriteLine("Invoking {0} with plugin '{1}' SUCCEEDED.", job.Id, job.Action);
+                            Trace.WriteLine("Invoking {0} with plugin '{1}' [ActivityId {2}] SUCCEEDED.", job.Id, job.Action, System.Diagnostics.Trace.CorrelationManager.ActivityId);
                         }
                         else
                         {
-                            Trace.WriteLine("Invoking {0} with plugin '{1}' FAILED.", job.Id, job.Action);
+                            Trace.WriteLine("Invoking {0} with plugin '{1}' [ActivityId {2}] FAILED.", job.Id, job.Action, System.Diagnostics.Trace.CorrelationManager.ActivityId);
                         }
                     }
                     catch (Exception ex)
                     {
-                        var message = string.Format("Invoking {0} with plugin '{1}' FAILED.", job.Id, job.Action);
+                        var message = string.Format("Invoking {0} with plugin '{1}' [ActivityId {2}] FAILED.", job.Id, job.Action, System.Diagnostics.Trace.CorrelationManager.ActivityId);
                         Trace.WriteException(message, ex);
                     }
                 }


removed unnused method

removed unnused method

--- UnityProject/Assets/Scripts/NPC/AI/StatueAI.cs
+++ UnityProject/Assets/Scripts/NPC/AI/StatueAI.cs
@@ -257,38 +257,6 @@
 		}
 	}

-	private void DoRandomMove()
-	{
-		var nudgeDir = GetNudgeDirFromInt(Random.Range(0, 8));
-		if (registerObject.Matrix.IsSpaceAt(registerObject.LocalPosition + nudgeDir.To3Int(), true))
-		{
-			for (int i = 0; i < 8; i++)
-			{
-				var testDir = GetNudgeDirFromInt(i);
-				var checkTile = registerObject.LocalPosition + testDir.To3Int();
-				if (!registerObject.Matrix.IsSpaceAt(checkTile, true))
-				{
-					if (registerObject.Matrix.IsPassableAt(checkTile, true))
-					{
-						nudgeDir = testDir;
-						break;
-					}
-					else
-					{
-						if (registerObject.Matrix.GetFirst<DoorController>(checkTile, true))
-						{
-							nudgeDir = testDir;
-							break;
-						}
-					}
-				}
-			}
-		}
-
-		NudgeInDirection(nudgeDir);
-		movementTickRate = Random.Range(1f, 3f);
-	}
-
 	void PlaySound()
 	{
 		if (!IsDead && !IsUnconscious && GenericSounds.Count > 0)


abs added for selectionlength

abs added for selectionlength

--- WalletWasabi.Gui/Controls/NoparaPasswordBox.cs
+++ WalletWasabi.Gui/Controls/NoparaPasswordBox.cs
@@ -40,7 +40,7 @@
 		private StringBuilder _sb = new StringBuilder();
 		private HashSet<Key> _supressedKeys;

-		public int SelectionLength => SelectionEnd - SelectionStart;
+		public int SelectionLength => Math.Abs(SelectionEnd - SelectionStart);

 		public static readonly StyledProperty<string> PasswordProperty =
 			AvaloniaProperty.Register<NoparaPasswordBox, string>(nameof(Password), defaultBindingMode: BindingMode.TwoWay);


CIT-480 cleared textarea values on stack events

--- Web/Areas/Hub/Views/StackEvent/EventLog.cshtml
+++ Web/Areas/Hub/Views/StackEvent/EventLog.cshtml
@@ -54,7 +54,10 @@

         $('#StackNumberTwo').val(stackValue.value());
         $('#StackTwoName').val(stackValue.text());
+

+        $('#Recommendation').val("");
+        $('#Description').val("");
     });


[general.wp] Mistake in comment referencing the C# spec

--- Windows/Source/Common/SettingsDefaultValues.cs
+++ Windows/Source/Common/SettingsDefaultValues.cs
@@ -48,7 +48,7 @@
             return ( (MemberExpression) expr.Body ).Member.Name;
         }

-        // Required for collection initializers, see §7.5.10.3 of the C# spec.
+        // Required for collection initializers, see §7.6.10.3 of the C# spec.
         public IEnumerator GetEnumerator()
         {
             throw new NotSupportedException();


TagList: Removed weird Add overload

TagList: Removed weird Add overload

--- sources/custom/TagList.cs
+++ sources/custom/TagList.cs
@@ -83,19 +83,6 @@
 			GLib.Marshaller.Free (raw_string);
 		}

-		public void Add (Gst.TagMergeMode mode, params object[] parameters)
-		{
-			if (parameters.Length % 2 != 0)
-				throw new ArgumentException ();
-
-			for (int i = 0; i < parameters.Length; i += 2) {
-				if (parameters [i].GetType () != typeof(string))
-					throw new ArgumentException ();
-
-				Add (mode, parameters [i] as string, parameters [i + 1]);
-			}
-		}
-
 		[DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
 		static extern IntPtr gst_structure_nth_field_name (IntPtr raw, uint index);


improved test for Fn.ErfInverse for 100% coverage


MakeNLogXSD - Improve xml-docs when summary contains cref

--- tools/MakeNLogXSD/XsdFileGenerator.cs
+++ tools/MakeNLogXSD/XsdFileGenerator.cs
@@ -221,9 +221,23 @@
                 var summary = doc.Element("summary");
                 if (summary != null)
                 {
+                    var summaryDoc = summary.Value;
+                    if (summary.HasElements)
+                    {
+                        summaryDoc = string.Empty;
+                        foreach (var item in summary.Nodes())
+                        {
+                            var element = item as XElement;
+                            if (element?.HasAttributes == true)
+                                summaryDoc += element.FirstAttribute.Value;
+                            else
+                                summaryDoc += item.ToString();
+                        }
+                    }
+
                     result.Add(new XElement(xsd + "annotation",
                         new XElement(xsd + "documentation",
-                            summary.Value)));
+                            summaryDoc)));
                 }
             }


Corrección menor.

Corrección menor.

--- YUTPLAT/Services/IndicadorAutomaticoService.cs
+++ YUTPLAT/Services/IndicadorAutomaticoService.cs
@@ -39,22 +39,22 @@
                         RecurringJob.AddOrUpdate<IndicadorAutomaticoCPIStrategy>(
                            indicadorAutomatico.Nombre,
                            x => x.EjecutarIndicador(indicadorAutomatico.IndicadorViewModel),
-                           Cron.Minutely);
-                           //Cron.Monthly(5, 1, 0)); // El 5 de cada mes a la 1:00 a.m.
+                           //Cron.Minutely);
+                           Cron.Monthly(5, 1, 0)); // El 5 de cada mes a la 1:00 a.m.
                         break;
                     case Enums.Enum.CategoriaIndicadorAutomatico.CPI_Servicios:
                         RecurringJob.AddOrUpdate<IndicadorAutomaticoCPIServiciosStrategy>(
                            indicadorAutomatico.Nombre,
                            x => x.EjecutarIndicador(indicadorAutomatico.IndicadorViewModel),
-                           Cron.Minutely);
-                           //Cron.Monthly(5, 1, 15)); // El 5 de cada mes a la 1:15 a.m.
+                           //Cron.Minutely);
+                           Cron.Monthly(5, 1, 15)); // El 5 de cada mes a la 1:15 a.m.
                         break;
                     case Enums.Enum.CategoriaIndicadorAutomatico.CPI_Llave_En_Mano:
                         RecurringJob.AddOrUpdate<IndicadorAutomaticoCPILlaveManoStrategy>(
                            indicadorAutomatico.Nombre,
                            x => x.EjecutarIndicador(indicadorAutomatico.IndicadorViewModel),
-                           Cron.Minutely);
-                           //Cron.Monthly(5, 1, 30)); // El 5 de cada mes a la 1:30 a.m.
+                           //Cron.Minutely);
+                           Cron.Monthly(5, 1, 30)); // El 5 de cada mes a la 1:30 a.m.
                         break;
                 }
             }


[Modify] Polish it

[Modify] Polish it

--- websocket-sharp/Net/HttpConnection.cs
+++ websocket-sharp/Net/HttpConnection.cs
@@ -420,31 +420,41 @@
       return false;
     }

-    private string readLineFrom (byte[] buffer, int offset, int length, out int read)
+    private string readLineFrom (
+      byte[] buffer, int offset, int length, out int read
+    )
     {
       read = 0;

-      for (var i = offset; i < length && _lineState != LineState.Lf; i++) {
+      for (var i = offset; i < length; i++) {
         read++;

         var b = buffer[i];
-        if (b == 13)
+
+        if (b == 13) {
           _lineState = LineState.Cr;
-        else if (b == 10)
+
+          continue;
+        }
+
+        if (b == 10) {
           _lineState = LineState.Lf;
-        else
-          _currentLine.Append ((char) b);
+
+          break;
+        }
+
+        _currentLine.Append ((char) b);
       }

       if (_lineState != LineState.Lf)
         return null;

-      var line = _currentLine.ToString ();
+      var ret = _currentLine.ToString ();

       _currentLine.Length = 0;
       _lineState = LineState.None;

-      return line;
+      return ret;
     }

     private void removeConnection ()


NIOFSDirectory is not implemented in Lucene.Net. So returning NIOFSDirectory as default directory on mono is wrong.

git-svn-id: b2dcba4c53c5fa0a86ccceee81d7e0ce197ae049@930561 13f79535-47bb-0310-9956-ffa450edef68

--- C#/src/Lucene.Net/Store/FSDirectory.cs
+++ C#/src/Lucene.Net/Store/FSDirectory.cs
@@ -565,7 +565,9 @@
 			}
 			else
 			{
-				return new NIOFSDirectory(path, lockFactory);
+                //NIOFSDirectory is not implemented in Lucene.Net
+				//return new NIOFSDirectory(path, lockFactory);
+                return new SimpleFSDirectory(path, lockFactory);
 			}
         }


feat: IAsset don't need to inherit IDisposable

--- Raccoon/Core/IAsset.cs
+++ Raccoon/Core/IAsset.cs
@@ -1,7 +1,7 @@
 using System.IO;

 namespace Raccoon {
-    public interface IAsset : System.IDisposable {
+    public interface IAsset {
         string Name { get; }
         //string Filename { get; }
         string[] Filenames { get; }
@@ -9,5 +9,6 @@

         void Reload();
         void Reload(Stream stream);
+        void Dispose();
     }
 }


Prohibit parent-child relationships from being doubled up

--- ReCoupler/ReCoupler.cs
+++ ReCoupler/ReCoupler.cs
@@ -516,6 +516,8 @@
             {
                 if (node.owner == checkNodes[j].owner)
                     continue; // Nodes on the same Part are not eligible.
+                if (node.owner.parent == checkNodes[j].owner || checkNodes[j].owner.parent == node.owner)
+                    continue; // Parent-child relationships don't need doubling up.

                 /*float dist = (Part.PartToVesselSpacePos(node.position, node.owner, node.owner.vessel, PartSpaceMode.Pristine) -
                     Part.PartToVesselSpacePos(checkNodes[j].position, checkNodes[j].owner, checkNodes[j].owner.vessel, PartSpaceMode.Pristine)).magnitude;


Simplified open source fixture to just Cake and Statiq

--- tests/Buildalyzer.Tests/Integration/OpenSourceProjectsFixture.cs
+++ tests/Buildalyzer.Tests/Integration/OpenSourceProjectsFixture.cs
@@ -30,11 +30,6 @@

         private static readonly TestRepository[] Repositories =
         {
-            new TestRepository(
-                "https://github.com/autofac/Autofac.git",
-                @"\bench\Autofac.Benchmarks\Autofac.Benchmarks.csproj"),
-            new TestRepository("https://github.com/AutoMapper/AutoMapper.git"),
-            new TestRepository(EnvironmentPreference.Framework, "https://github.com/serilog/serilog.git"), // SourceLink messed up from AppVeyor on SDK: "SourceLink.Create.CommandLine.dll. Assembly with same name is already loaded Confirm that the <UsingTask> declaration is correct"
             new TestRepository("https://github.com/cake-build/cake"),
             new TestRepository("https://github.com/statiqdev/Statiq.Framework.git")
         };


Make screen space be the topmost window

Make screen space be the topmost window

make top most window be the end of all windows in the parent list (last)

--- Gui/GUIWidget.cs
+++ Gui/GUIWidget.cs
@@ -2378,8 +2378,7 @@
 		{
 			GuiWidget prevGUIWidget = this;

-			while (prevGUIWidget != null
-				&& !(prevGUIWidget is SystemWindow))
+			while (prevGUIWidget != null)
 			{
 				vectorToTransform += prevGUIWidget.OriginRelativeParent;
 				prevGUIWidget = prevGUIWidget.Parent;
@@ -2390,7 +2389,7 @@

 		public GuiWidget TopmostParent()
 		{
-			return this.Parents<SystemWindow>().FirstOrDefault() ?? this.Parents<GuiWidget>().Last();
+			return this.Parents<GuiWidget>().Last();
 		}

 		public Vector2 TransformFromScreenSpace(Vector2 vectorToTransform)


Fixed x0 y0 == center Bug! thx to maul.esel

--- Rusty/Cores/Gui/Gui.cs
+++ Rusty/Cores/Gui/Gui.cs
@@ -139,7 +139,7 @@

                         var screen = Screen.PrimaryScreen.Bounds;

-                        if (location.IsEmpty)
+                        if (location == null)
                             center = true;

                         if (center)


--Fixed syntax issue in CellReferenceToCoordinates with int[] declaration, set VerboseLogging to true, and tweaked column names/data types.

--- SSIS_OpenXML_script.cs
+++ SSIS_OpenXML_script.cs
@@ -1,18 +1,21 @@
 /* Microsoft SQL Server Integration Services Script Component
 *  Write scripts using Microsoft Visual C# 2008.
 *  ScriptMain is the entry point class of the script.*/
+
 using System;
 using System.Collections.Generic;
 using System.Data;
 using System.Linq;
 using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
 using Microsoft.SqlServer.Dts.Runtime.Wrapper;
+using DocumentFormat.OpenXml;
 using DocumentFormat.OpenXml.Packaging;
 using DocumentFormat.OpenXml.Spreadsheet;
-using DocumentFormat.OpenXml;
+
 [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
 public class ScriptMain : UserComponent
 {
+
     #region Script Setup
     // Ensure you've set up output columns and supplied an Excel Connection Manager in the Script Editor UI
     /// <summary>
@@ -23,7 +26,7 @@
     /// <summary>
     /// Set this variable to true if you want copious reporting done (for debugging)
     /// </summary>
-    private static readonly bool VerboseLogging = false;
+    private static readonly bool VerboseLogging = true;
     /// <summary>
     /// Fill this method with calls to MapColumn to map Excel column names to SSIS output columns, and provide data types.
     /// </summary>
@@ -33,8 +36,9 @@
         // this.MapColumn("Excel Column Header", "SSIS Column Name", typeof(string));
         this.MapColumn("FA", "FA", typeof(string), true);
         this.MapColumn("USID", "USID", typeof(int), true);
-        this.MapColumn("OOF VENDOR TYPE", "OOF_Vendor_Type", typeof(string), true);
-        this.MapColumn("ECD", "ECD", typeof(string), true);
+        this.MapColumn("OOF_Vendor_Type", "OOF_Vendor_Type", typeof(string), true); // OOF VENDOR TYPE
+        // this.MapColumn("ECD", "ECD", typeof(string), true);
+        this.MapColumn("ECD", "ECD", typeof(int), true);
         this.MapColumn("Revised ECD", "Revised_ECD", typeof(string), true);
         this.MapColumn("ACD", "ACD", typeof(string), true);
         this.MapColumn("ACD 2", "ACD_2", typeof(string), true);
@@ -252,7 +256,7 @@
     #endregion

     #region Sets up map from Excel column to an SSIS column
-    private void MapColumn(string excelColumnName, string ssisColumnName, System.Type dataType, bool treatBlanksAsNulls)
+    public void MapColumn(string excelColumnName, string ssisColumnName, System.Type dataType, bool treatBlanksAsNulls)
     {
         string methodName = "set_" + ssisColumnName.Replace(" ", "");
         VerboseLog("Creating " + dataType.ToString() + " mapping from '" + excelColumnName + "' to '" + ssisColumnName + "' via " + methodName);
@@ -546,7 +550,7 @@
     private int[] CellReferenceToCoordinates(string cellReference)
     {
         //bool fireAgain = true;
-        t[] coordinates = new int[2];
+        int[] coordinates = new int[2];

         //ComponentMetaData.FireInformation(0, "", "CellRef: [" + cellReference + "]", "", 0, ref fireAgain);
         int index;
@@ -633,4 +637,31 @@
         throw new ArgumentException("This script can't handle " + dataType.ToString() + " types.");
     }
     #endregion
-}+
+    //public override void PreExecute()
+    //{
+    //    base.PreExecute();
+    //    /*
+    //      Add your code here for preprocessing or remove if not needed
+    //    */
+    //}
+
+    //public override void PostExecute()
+    //{
+    //    base.PostExecute();
+    //    /*
+    //      Add your code here for postprocessing or remove if not needed
+    //      You can set read/write variables here, for example:
+    //      Variables.MyIntVar = 100
+    //    */
+    //}
+
+    //public override void CreateNewOutputRows()
+    //{
+    //    /*
+    //      Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
+    //      For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
+    //    */
+    //}
+
+}


added show cart view

added show cart view

--- e-commerce/Views/Cart/ShowCart.cshtml
+++ e-commerce/Views/Cart/ShowCart.cshtml
@@ -1,4 +1,4 @@
-@model e_commerce.Models.ProductsViewModel
+@model List<e_commerce.Models.CartViewModel>
 @{
     ViewBag.Title = "ShowCart";
 }
@@ -6,15 +6,20 @@

Your cart

+          @foreach (var cart in Model)
+          {
+

+
@cart.ProductName

+

+
@cart.ProductDescription

+                Price @cart.ProductPrice

+
Quantity

+                <input type="number" name="cartQuantity" value="@cart.Quantity" />

+                <input type="submit" name="Delete" value="Delete product" />
+                <input type="submit" name="Add" value="Change quantity" />
+

+          }

-        @foreach (var cart in Model)
-        {
-

-
@cart.ProductName

-
@cart.ProductDescription

-                @cart.ProductPrice
-

-        }


Add unloading support to Map

Add unloading support to Map

Adds various options for unloading chunks, broadly divided into two
categories: Expiration and Area and intersections between them.

--- InfiniMap/Map.cs
+++ InfiniMap/Map.cs
@@ -1,20 +1,55 @@
 using System;
+using System.Collections;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;

 namespace InfiniMap
 {
+    /// <summary>
+    /// Provides support for attaching Expiration to objects
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    public class CacheEntry<T>
+    {
+        private DateTime _expiration;
+        private readonly object _lock = new object();
+
+        public T Value { get; private set; }
+
+        public DateTime Expiration
+        {
+            get { lock (_lock) { return _expiration; } }
+            private set { lock (_lock) { _expiration = value; } }
+        }
+
+        public CacheEntry(T value, DateTime expiration)
+        {
+            Expiration = expiration;
+            Value = value;
+        }
+
+        public void Refresh()
+        {
+            lock (_lock)
+            {
+                Expiration = DateTime.Now;
+            }
+        }
+    }
+
     public class Map
     {
-        public IDictionary<Tuple<int, int>, Chunk> Chunks;
-
-        private int _chunkWidth;
-        private int _chunkHeight;
+        public IDictionary<Tuple<int, int>, CacheEntry<Chunk>> Chunks;
+
+        private readonly int _chunkWidth;
+        private readonly int _chunkHeight;

         public Map(int chunkHeight, int chunkWidth)
         {
             _chunkHeight = chunkHeight;
             _chunkWidth = chunkWidth;
-            Chunks = new Dictionary<Tuple<int, int>, Chunk>(64);
+            Chunks = new Dictionary<Tuple<int, int>, CacheEntry<Chunk>>(64);
         }

         private IEnumerable<Tuple<int, int>> Distance(int startX, int startY, int range)
@@ -23,7 +58,8 @@
         }

         /// <summary>
-        /// Very simple garbage collection, frees all chunks within the given range.
+        /// Unload all chunks within a given area.
+        /// Ignores expiration, all chunks are unloaded; expired or not.
         /// </summary>
         /// <remarks>
         /// Frees up chunks in a square pattern. Given (0,0) and a range of 1, free:
@@ -42,6 +78,104 @@
             }
         }

+        /// <summary>
+        /// Unload everything except the defined area.
+        /// Ignores expiration, all chunks are unloaded, expired or not.
+        /// </summary>
+        /// <remarks>
+        /// Frees chunks with a square pattern being kept in memory. Given (1,1) and a range of 1:
+        /// (0,0) (0,1) (0,2)
+        /// (1,0) [1,1] [1,2]
+        /// (2,0) [2,1] [2,2]
+        /// (3,0) (3,1) (2,2)
+        ///
+        /// [x,y] are kept in memory, (x,y) are discared from memory.
+        /// </remarks>
+        /// <param name="curX">Chunk X to start from</param>
+        /// <param name="curY">Chunk Y to start from</param>
+        /// <param name="range">Square distance to keep in memory</param>
+        public void UnloadAreaInverted(int curX, int curY, int range)
+        {
+            var localChunks = Distance(curX, curY, range).ToList();
+            // Clean out chunks outside of (x,y) -> (x+range, y+range)
+            foreach (var pair in Chunks.Where(pair => !localChunks.Contains(pair.Key)))
+            {
+                Chunks.Remove(pair.Key);
+            }
+        }
+
+        /// <summary>
+        /// Unload all expired blocks within a given area.
+        /// </summary>
+        /// <remarks>
+        /// Follows the same selection rules as <seealso cref="UnloadArea"/> except for
+        /// considering expiration of chunks.
+        /// </remarks>
+        /// <param name="expiryTime">Expiry time to use, any chunks last accessed before this point are unloaded</param>
+        /// <param name="curX">Chunk X to start from</param>
+        /// <param name="curY">Chunk Y to start from</param>
+        /// <param name="range">Square distance to unload</param>
+        public void UnloadExpiredArea(DateTime expiryTime, int curX, int curY, int range)
+        {
+            CacheEntry<Chunk> chunk = null;
+            foreach (var result in Distance(curX, curY, range).Select(pair => new {pair, found = Chunks.TryGetValue(pair, out chunk)}).Where(
+                    result => result.found).Where(result => chunk.Expiration <= expiryTime)) {
+                Chunks.Remove(result.pair);
+            }
+        }
+
+        /// <summary>
+        /// Unload all expired blocks outside of the defined area.
+        /// </summary>
+        /// <remarks>
+        /// Follows the same selection rules as <seealso cref="UnloadAreaInverted"/> except for
+        /// considering expiration of chunks.
+        /// </remarks>
+        /// <param name="expiryTime">Expiry time to use, any chunks last accessed before this point are unloaded</param>
+        /// <param name="curX">Chunk X to start from</param>
+        /// <param name="curY">Chunk Y to start form</param>
+        /// <param name="range">Square distance to unload</param>
+        public void UnloadedExpiredAreaInverted(DateTime expiryTime, int curX, int curY, int range)
+        {
+            CacheEntry<Chunk> chunk = null;
+            var localChunks = Distance(curX, curY, range).ToList();
+            // Clean out chunks outside of (x,y) -> (x+range,y+range) where Expiration <= expiryTime
+            foreach (var result in Chunks.Select(pair => new {key = pair.Key, found = Chunks.TryGetValue(pair.Key, out chunk)}).Where(
+                result => result.found).Where(pair => !localChunks.Contains(pair.key)).Where(result => chunk.Expiration <= expiryTime))
+            {
+                Chunks.Remove(result.key);
+            }
+        }
+
+        /// <summary>
+        /// Unload all expired blocks.
+        /// This does not account for keeping any blocks in memory.
+        /// </summary>
+        /// <param name="expiryTime">Expiry time to use, any chunks last accessed before this point are unloaded</param>
+        public void UnloadExpired(DateTime expiryTime)
+        {
+            foreach (var pair in Chunks.Where(x => x.Value.Expiration <= expiryTime))
+            {
+                Chunks.Remove(pair.Key);
+            }
+        }
+
+        /// <summary>
+        /// Save a world into <paramref name="folderPath"/>
+        /// </summary>
+        /// <param name="folderPath">Root world folder to save into</param>
+        public void Write(string folderPath)
+        {
+        }
+
+        /// <summary>
+        /// Load a worldmap from <paramref name="folderPath"/>
+        /// </summary>
+        /// <param name="folderPath">Root world folder to load from</param>
+        public void Read(string folderPath)
+        {
+        }
+
         public Block this[int x, int y]
         {
             get
@@ -49,21 +183,22 @@
                 var xChunk = (int) Math.Floor(x/(float) _chunkHeight);
                 var yChunk = (int) Math.Floor(y/(float) _chunkWidth);

-                Chunk chunk;
+                CacheEntry<Chunk> chunk;
                 var foundChunk = Chunks.TryGetValue(Tuple.Create(xChunk, yChunk), out chunk);
                 if (foundChunk)
                 {
-                    return chunk[x, y];
+                    chunk.Refresh();
+                    return chunk.Value[x, y];
                 }

                 var newChunk = new Chunk(_chunkHeight, _chunkWidth);
-                Chunks.Add(Tuple.Create(xChunk, yChunk), newChunk);
+                Chunks.Add(Tuple.Create(xChunk, yChunk), new CacheEntry<Chunk>(newChunk, DateTime.Now));
                 return newChunk[x, y];
             }
             set
             {
                 // Block is a reference type, so we just discard a local pointer after
-                // alterting the object
+                // altering the object
                 var block = this[x, y];
                 block = value;
             }


include generated files into JNIBridgeTests

--- JniBridge.bee.cs
+++ JniBridge.bee.cs
@@ -173,7 +173,7 @@
         ZipTool.SetupPack(androidZipPath, androidZip);
         Backend.Current.AddAliasDependency("build:android:zip", androidZipPath);

-        SetupGeneratedProjects(nativePrograms, windowsTestProgram, targetExecutable);
+        SetupGeneratedProjects(nativePrograms, windowsTestProgram, generatedFilesWindows, targetExecutable);
     }

     static Jdk SetupJava()
@@ -502,7 +502,7 @@
         throw new NotImplementedException(architecture.ToString());
     }

-    static void SetupGeneratedProjects(IReadOnlyList<NativeProgram> programs, NativeProgram testingProgram, NPath executableForTests)
+    static void SetupGeneratedProjects(IReadOnlyList<NativeProgram> programs, NativeProgram testingProgram, NPath generatedFilesDirectory, NPath executableForTests)
     {
         // Not entirely sure, but I think there's should have been only NativeProgram with different architectures.
         // Yet we have 4
@@ -568,7 +568,15 @@
             return @$"{setAndroidSDKRoot}
 bee build:windows:test";
         });
-        builder = new VisualStudioNativeProjectFileBuilder(testingProgram, extraFiles);
+
+        var extraFilesForTests = new List<NPath>();
+        extraFilesForTests.AddRange(HeaderFiles);
+        extraFilesForTests.AddRange(CppFiles);
+        extraFilesForTests.AddRange(JavaFiles);
+        // Includes generated files for Windows, we don't want those in JNIBridge project since it builds for Android
+        extraFilesForTests.AddRange(generatedFilesDirectory.Files(true));
+
+        builder = new VisualStudioNativeProjectFileBuilder(testingProgram, extraFilesForTests);
         builder = testingProgram.SetupConfigurations.Aggregate(
             builder,
             (current, c) => current.AddProjectConfiguration(c)


Fix description

Fix description

--- AssemblyPoolLibrary/Library/Properties/AssemblyInfo.cs
+++ AssemblyPoolLibrary/Library/Properties/AssemblyInfo.cs
@@ -7,7 +7,7 @@
 // set of attributes. Change these attribute values to modify the information
 // associated with an assembly.
 [assembly: AssemblyTitle("AssemblyPoolLibrary")]
-[assembly: AssemblyDescription("Contains three classes with dependency between them, ProjectNameContainer is a public non-static class with")]
+[assembly: AssemblyDescription("Contains three classes with dependency between them, ProjectNameContainer is a public non-static")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("Library")]


Exceptions: added constructor that takes a IList to vIndexOutOfRange

--- Assets/Plugins/Vexe/Runtime/Types/Others/Exceptions.cs
+++ Assets/Plugins/Vexe/Runtime/Types/Others/Exceptions.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Collections;

 namespace System
 {
@@ -48,5 +49,9 @@
             : base("Index `" + outOfRangeIndex + "` should be greater or equal to zero and less than the total count of `" + totalCount + "`")
         {
         }
+
+        public vIndexOutOfRange(int outOfRangeIndex, IList list) : this(outOfRangeIndex, list.Count)
+        {
+        }
     }
-}+}


Use simple types (instead of var) in Deck Generator

--- Assets/Scripts/HarryPotterUnity/Utils/DeckGenerator.cs
+++ Assets/Scripts/HarryPotterUnity/Utils/DeckGenerator.cs
@@ -91,7 +91,7 @@
             var card = CardLibrary.Where(c => c.Classification == GenericCard.ClassificationTypes.Lesson)
                 .First(l => ((Lesson) l).LessonType == lessonType);

-            for (var i = 0; i < amount; i++)
+            for (int i = 0; i < amount; i++)
             {
                 deck.Add(card);
             }
@@ -101,11 +101,11 @@
         {
             var potentialCards = CardLibrary.Where(c => c.Classification == classification).ToList();

-            var cardsAdded = 0;
+            int cardsAdded = 0;

             while (cardsAdded < amount)
             {
-                var selected = Random.Range(0, potentialCards.Count);
+                int selected = Random.Range(0, potentialCards.Count);
                 var card = potentialCards[selected];

                 //TODO: Enable this check when enough cards are implemented


Revert SerializedNestedStrings

Revert SerializedNestedStrings

--- Assets/Scripts/Localization/SerializedNestedStrings.cs
+++ Assets/Scripts/Localization/SerializedNestedStrings.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Text.RegularExpressions;

 //Class is used like a dicationary : instance[key] = value
@@ -8,7 +7,7 @@
 //Serialization uses tabs for group indentation, key=value for string value lines
 //ToString() returns serialized data

-public class SerializedNestedStrings
+class SerializedNestedStrings
 {
     private class StringData
     {
@@ -17,66 +16,65 @@

         public StringData()
         {
-            subData = new Dictionary<string, StringData>(StringComparer.OrdinalIgnoreCase);
+            subData = new Dictionary<string, StringData>();
         }
     }

-    private Dictionary<string, StringData> data;
+    private StringData rootData;

     public SerializedNestedStrings()
     {
-        data = new Dictionary<string, StringData>(StringComparer.OrdinalIgnoreCase);
+        rootData = new StringData();
     }

     public object getData()
     {
-        return data;
+        return rootData;
     }

     public string this[string index]
     {
         get
         {
-            return string.IsNullOrEmpty(index) ? null : getString(data, new List<string>(index.Split('.')));
+            return string.IsNullOrEmpty(index) ? null : getString(rootData, new List<string>(index.Split('.')));
         }
         set
         {
-            setString(data, new List<string>(index.Split('.')), value);
+            setString(rootData, new List<string>(index.Split('.')), value);
         }
     }

-    private string getString(Dictionary<string, StringData> baseObject, List<string> keys)
+    private string getString(StringData baseData, List<string> keys)
     {
         if (keys.Count == 1)
         {
             //We are at deepest nesting level
-            return baseObject.ContainsKey(keys[0]) ? baseObject[keys[0]].value : null;
+            return baseData.subData.ContainsKey(keys[0]) ? baseData.subData[keys[0]].value : null;
         }
         else
         {
             //We are not at deepest nesting level
             string currentKey = keys[0];
             keys.RemoveAt(0);
-            var thing = baseObject[currentKey];
-            return baseObject.ContainsKey(currentKey) ? getString((baseObject[currentKey].subData), keys) : null;
+            return baseData.subData.ContainsKey(currentKey) ? getString((baseData.subData[currentKey]), keys) : null;
         }
     }

-    private void setString(Dictionary<string, StringData> baseObject, List<string> keys, string value)
+    private void setString(StringData baseData, List<string> keys, string value)
     {
         if (keys.Count == 1)
         {
             //We are at deepest nesting level
-            if (!baseObject.ContainsKey(keys[0]))
-                baseObject[keys[0]] = new StringData();
-            baseObject[keys[0]].value = value;
+            if (!baseData.subData.ContainsKey(keys[0]))
+                baseData.subData[keys[0]] = new StringData();
+            baseData.subData[keys[0]].value = value;
         }
-        else if (baseObject.ContainsKey(keys[0]))
+        else if (baseData.subData.ContainsKey(keys[0]))
         {
             //Not at deepest nesting level but dictionary with same name exists
-            Dictionary<string, StringData> existingObject = baseObject[keys[0]].subData;
+            StringData existingData = baseData.subData[keys[0]];
             keys.RemoveAt(0);
-            setString(existingObject, keys, value);
+            setString(existingData, keys, value);
         }
         else
         {
@@ -84,91 +82,82 @@
             StringData newData = new StringData();
             string currentKey = keys[0];
             keys.RemoveAt(0);
-            baseObject[currentKey] = newData;
-            setString(newData.subData, keys, value);
+            baseData.subData[currentKey] = newData;
+            setString(newData, keys, value);
         }
     }

     public override string ToString()
     {
-        string result = serialize(data, 0);
+        string result = serialize(rootData, 0);
         return result == "" ? result : result.Substring(0, result.Length - 1);
     }

-    string serialize(Dictionary<string, StringData> baseObject, int nestLevel)
+    string serialize(StringData baseData, int nestLevel)
     {
         //Minimalist serialization, tabs for group hierarchy, "key=value" at lowest level
         string result = "";
-        foreach (KeyValuePair<string, StringData> entry in baseObject)
+        foreach (KeyValuePair<string, StringData> entry in baseData.subData)
         {
             result += new string('\t', nestLevel);
-            result += entry.Key + (string.IsNullOrEmpty(entry.Value.value) ? "" : "=" + entry.Value.value) + "\n";
+            if (!string.IsNullOrEmpty(entry.Value.value))
+                result += entry.Key + "=" + (string)entry.Value.value + "\n";
             if (entry.Value.subData.Count > 0)
             {
-                result += serialize(entry.Value.subData, nestLevel + 1);
+                result += entry.Key + "\n";
+                result += serialize(entry.Value, nestLevel + 1);
             }
         }
         return result;
     }

-    public static SerializedNestedStrings deserialize(string serializedData)
+    public static SerializedNestedStrings deserialize(string serializedData, SerializedNestedStrings existingStrings = null)
     {
         serializedData = serializedData.Replace(((char)13).ToString(), ""); //Remove any instances of carriage return
+        if (existingStrings == null)
+            existingStrings = new SerializedNestedStrings();

-        List<string> lines = new List<string>(serializedData.Split('\n'));
-        SerializedNestedStrings newData = new SerializedNestedStrings();
+        deserializeData(existingStrings.rootData, serializedData.Split('\n'), 0, 0);
+        return existingStrings;
+    }

-        string currentKeyBase = "";
-        for (int i = 0; i < lines.Count; i++)
+    private static int deserializeData(StringData baseData, string[] lines, int startLine, int tabCount)
+    {
+        string line = lines[startLine];
+
+        for (int i = startLine; i < lines.Length; i++)
         {
-            string line = lines[i];
-            int tabCount = getTabCount(line),
-                dotCount = currentKeyBase.Split('.').Length - 1;
-            while (tabCount < dotCount)
-            {
-                //Key is up from previous line in hierarchy
-                //Remove "{key}." from current hierarchy string to go up one level
-                if (dotCount == 1)
-                    currentKeyBase = "";
-                else
-                    currentKeyBase = Regex.Replace(currentKeyBase, @"(.*)\.[^\.]*.$", @"$1.");      //Replace last ".[string]." with "."
-                dotCount--;
-            }
+            line = lines[i];
+            if (getTabCount(line) < tabCount)   //We haven't finished recursing and line tab count is less than expected
+                return i - 1;   //Return previous line so we we can reevaulate this line on previous level
+
+            string key = Regex.Replace(lines[i].Split('=')[0], @"^\t*", "");    //String between leading tabs and "="
+            StringData newData = new StringData();
+            baseData.subData[key] = newData;
             if (line.Contains("="))
             {
                 //line is string value, add to deserialized data
-                string key = Regex.Replace(line.Split('=')[0], @"^\t*", ""),    //String between leading tabs and "="
-                    value = Regex.Replace(line, @"^[^=]*=(.*)", @"$1");         //String after first "="
-                newData[currentKeyBase + key] = value;
+                string value = Regex.Replace(line, @"^[^=]*=(.*)", @"$1");         //String after first "="
+                newData.value = value;
             }
-            if (i < lines.Count - 1 && getTabCount(lines[i + 1]) > tabCount)
+
+            if (i + 1 < lines.Length)
             {
-                //line is beginning of a group because next line has more tabs (and exists), increase nest level by adding line to keystring base
-                currentKeyBase += Regex.Replace(line.Split('=')[0], @"^\t*", "") + ".";     //String between leading tabs and "=" (if there is one)
-
+                int nextLineTabCount = getTabCount(lines[i + 1]);
+                if (nextLineTabCount > tabCount)
+                {
+                    //Next line has more tabs than this one, recurse into next level
+                    i = deserializeData(newData, lines, i + 1, tabCount + 1);
+                }
+                else if (nextLineTabCount < tabCount)
+                {
+                    //Next line is no longer on or beneath this level, return what line we're on
+                    return i;
+                }
             }
         }
-
-        return newData;
+        return lines.Length;
     }
-
-    //public List<string> flatten()
-    //{
-    //    return flatten(data);
-    //}
-
-    //List<string> flatten(Dictionary<string, StringData> data)
-    //{
-    //    var returnList = from subdata in data
-    //                     where !string.IsNullOrEmpty(subdata.Value.value)
-    //                     select subdata;
-    //    var returnList = data.Where(a => !string.IsNullOrEmpty(a.Value.value)).Select(a => a.Value.value).ToList();
-    //    foreach (var subList in data.Select(a => a.Value.subData).Where(a => a != null && a.Any()))
-    //    {
-    //        returnList.AddRange(flatten(subList));
-    //    }
-    //    return returnList;
-    //}

     static int getTabCount(string line)
     {


Fix localization bug when going up multiple levels

--- Assets/Scripts/Localization/SerializedNestedStrings.cs
+++ Assets/Scripts/Localization/SerializedNestedStrings.cs
@@ -1,6 +1,5 @@
 using System.Collections.Generic;
 using System.Text.RegularExpressions;
-using UnityEngine;

 //Class is used like a dicationary : instance[key] = value
 //Key can have nested values denoted by ".", automatically organizing them hierarchically (i.e. "microgame.ChenFood.command")
@@ -126,24 +125,15 @@
         return existingStrings;
     }

-    static void debugDisplay(StringData data, string key)
-    {
-
-        Debug.Log(key + " : " + data.value);
-        foreach (var item in data.subData)
-        {
-            debugDisplay(item.Value, key + (key.Equals("") ? "" : ".") + item.Key);
-        }
-    }
-
     private static int deserializeData(StringData baseData, string[] lines, int startLine, int tabCount)
     {
         string line = lines[startLine];

         for (int i = startLine; i < lines.Length; i++)
         {
-            i = i + (tabCount * 0);
             line = lines[i];
+            if (getTabCount(line) < tabCount)   //We haven't finished recursing and line tab count is less than expected
+                return i - 1;   //Return previous line so we we can reevaulate this line on previous level

             string key = Regex.Replace(lines[i].Split('=')[0], @"^\t*", "");    //String between leading tabs and "="
             StringData newData = new StringData();


added edit button

added edit button

--- Badges/Views/Shared/_ExperienceOutcomesFeedback.cshtml
+++ Badges/Views/Shared/_ExperienceOutcomesFeedback.cshtml
@@ -16,7 +16,17 @@

                     @foreach (var outcome in Model.ExperienceOutcomes.Where(x=>x.Outcome.Name == outcomeCategory).ToArray())
                     {
-
@string.Format("{0:D}", outcome.Created)

+

+                            @string.Format("{0:D}", outcome.Created)
+
+                                <form>
+                                    @Html.AntiForgeryToken()
+                                    <button type="submit" class="btn-xs">
+
+                                    </button>
+                                </form>
+
+

                     }