Optimizing sender channel to skipping modules when there's is none.

--- src/Lime.Protocol/Network/SenderChannel.cs
+++ src/Lime.Protocol/Network/SenderChannel.cs
@@ -26,12 +26,12 @@
         private readonly ActionBlock<Envelope> _sendEnvelopeBlock;
         private readonly object _syncRoot;
         private readonly SemaphoreSlim _sessionSemaphore;
+        private readonly ITargetBlock<Envelope> _skipModulesTargetBlock; // Optimization: Reference to the target block to send directly skipping the modules

         private bool _isDisposing;
         private readonly Timer _flushBatchTimer;
         private readonly TimeSpan _flushBatchInterval;

-
         public SenderChannel(
             IChannelInformation channelInformation,
             ITransport transport,
@@ -58,6 +58,7 @@
             _sessionSemaphore = new SemaphoreSlim(1);

             // Send pipeline
+            // Modules blocks
             _senderCts = new CancellationTokenSource();
             var raiseModulesDataflowBlockOptions = new ExecutionDataflowBlockOptions()
             {
@@ -78,13 +79,13 @@
                 EnsureOrdered = false,
             };

+            // Create the after modules pipeline, depending if it is batched or not.
             if (sendBatchSize <= 1)
             {
                 // Single mode, send directly to the the send block
-                _sendEnvelopeBlock = new ActionBlock<Envelope>(
+                _skipModulesTargetBlock = _sendEnvelopeBlock = new ActionBlock<Envelope>(
                     e => SendToTransportAsync(e, _senderCts.Token),
                     sendDataflowBlockOptions);
-
                 _messageToEnvelopeTransformBlock.LinkTo(_sendEnvelopeBlock,
                     DataflowUtils.PropagateCompletionLinkOptions);
                 _notificationToEnvelopeTransformBlock.LinkTo(_sendEnvelopeBlock,
@@ -95,7 +96,7 @@
             else
             {
                 // Batched mode, create a batch block between the modules block and the send block
-                _envelopeBatchBlock = new BatchBlock<Envelope>(
+                _skipModulesTargetBlock = _envelopeBatchBlock = new BatchBlock<Envelope>(
                     sendBatchSize,
                     new GroupingDataflowBlockOptions()
                     {
@@ -133,13 +134,19 @@
         }

         public Task SendMessageAsync(Message message, CancellationToken cancellationToken)
-            => SendAsync(message, _messageToEnvelopeTransformBlock, cancellationToken);
+            =>  _messageModules.Count > 0
+                ? SendAsync(message, _messageToEnvelopeTransformBlock, cancellationToken)
+                : SendAsync(message, _skipModulesTargetBlock, cancellationToken); // Skip modules if there's none to optimize the pipeline

         public Task SendNotificationAsync(Notification notification, CancellationToken cancellationToken)
-            => SendAsync(notification, _notificationToEnvelopeTransformBlock, cancellationToken);
+            =>  _notificationModules.Count > 0
+                ? SendAsync(notification, _notificationToEnvelopeTransformBlock, cancellationToken)
+                : SendAsync(notification, _skipModulesTargetBlock, cancellationToken);

         public Task SendCommandAsync(Command command, CancellationToken cancellationToken)
-            => SendAsync(command, _commandToEnvelopeTransformBlock, cancellationToken);
+            =>  _commandModules.Count > 0
+                ? SendAsync(command, _commandToEnvelopeTransformBlock, cancellationToken)
+                : SendAsync(command, _skipModulesTargetBlock, cancellationToken);

         public async Task SendSessionAsync(Session session, CancellationToken cancellationToken)
         {
@@ -193,10 +200,10 @@
         }

         /// <summary>
-        /// Sends the envelope to the transport.
+        /// Sends the envelope to the specified target.
         /// </summary>
         private async Task SendAsync<T>(T envelope, ITargetBlock<T> targetBlock, CancellationToken cancellationToken)
-            where T : Envelope, new()
+            where T : Envelope
         {
             if (envelope == null) throw new ArgumentNullException(nameof(envelope));
             if (_channelInformation.State != SessionState.Established)
@@ -215,7 +222,6 @@
                 throw new InvalidOperationException("The send buffer is complete",
                     targetBlock.Completion.Exception?.GetBaseException());
             }
-
             if (!await targetBlock.SendAsync(envelope, cancellationToken).ConfigureAwait(false))
             {
                 throw new InvalidOperationException("The send buffer is not accepting more envelopes");


fix move segment up crash when on last line

--- src/MarkdownEdit/Models/EditorUtilities.cs
+++ src/MarkdownEdit/Models/EditorUtilities.cs
@@ -178,7 +178,10 @@
             {
                 var text = document.GetText(segment.Offset, segment.TotalLength);
                 document.Remove(segment.Offset, segment.TotalLength);
-                document.Insert(document.GetOffset(currentLine, 0), text);
+                var offset = currentLine >= document.LineCount
+                    ? document.TextLength
+                    : document.GetOffset(currentLine, 0);
+                document.Insert(offset, text);
                 textArea.Caret.Line = currentLine - 1;
                 textArea.Caret.BringCaretToView();
             }


Check for forum notifications more often.

--- src/MitternachtBot/Common/TimeConstants.cs
+++ src/MitternachtBot/Common/TimeConstants.cs
@@ -3,6 +3,6 @@
 		public const int WaitForForum      = 500;
 		public const int TeamUpdate        = 3 * 60 * 1000;
 		public const int Birthday          = 60 * 1000;
-		public const int ForumNotification = 1 * 60 * 1000;
+		public const int ForumNotification = 30 * 1000;
 	}
 }


Fix trust setting.

Fix trust setting.

--- src/MsgPack.Rpc/Properties/AssemblyInfo.cs
+++ src/MsgPack.Rpc/Properties/AssemblyInfo.cs
@@ -31,6 +31,7 @@
 [assembly: AssemblyFileVersion( "0.2.0.0" )]

 [assembly: SecurityRules( SecurityRuleSet.Level2, SkipVerificationInFullTrust = true )]
+[assembly: AllowPartiallyTrustedCallers]

 [assembly: InternalsVisibleTo( "MsgPack.Rpc.Client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a967de8de9d45380b93a6aa56f64fc2cb2d3c9d4b400e00de01f31ba9e15cf5ca95926dbf8760cce413eabd711e23df0c133193a570da8a3bb1bdc00ef170fccb2bc033266fa5346442c9cf0b071133d5b484845eab17095652aeafeeb71193506b8294d9c8c91e3fd01cc50bdbc2d0eb78dd655bb8cd0bd3cdbbcb192549cb4" )]
 [assembly: InternalsVisibleTo( "MsgPack.Rpc.Server, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a967de8de9d45380b93a6aa56f64fc2cb2d3c9d4b400e00de01f31ba9e15cf5ca95926dbf8760cce413eabd711e23df0c133193a570da8a3bb1bdc00ef170fccb2bc033266fa5346442c9cf0b071133d5b484845eab17095652aeafeeb71193506b8294d9c8c91e3fd01cc50bdbc2d0eb78dd655bb8cd0bd3cdbbcb192549cb4" )]


IDomainRepository doc

IDomainRepository doc

--- src/MyCQRS.EventStore/IDomainRepository.cs
+++ src/MyCQRS.EventStore/IDomainRepository.cs
@@ -2,9 +2,24 @@

 namespace MyCQRS.EventStore
 {
+    /// <summary>
+    /// Represents an abstraction where an instance of <see cref="IAggregate"/> will be persisted.
+    /// </summary>
     public interface IDomainRepository
     {
+        /// <summary>
+        /// Retrieves an <typeparam name="TAggregate"></typeparam> based on your unique identifier property.
+        /// </summary>
+        /// <typeparam name="TAggregate"></typeparam>
+        /// <param name="id"></param>
+        /// <returns></returns>
         TAggregate GetById<TAggregate>(Guid id) where TAggregate : class, IAggregate, new();
+
+        /// <summary>
+        /// Add an instance of <typeparam name="TAggregate"></typeparam> in repository.
+        /// </summary>
+        /// <typeparam name="TAggregate"></typeparam>
+        /// <param name="aggregate"></param>
         void Add<TAggregate>(TAggregate aggregate) where TAggregate : class, IAggregate;
     }
 }


Improvements to integer factorization answer.

--- src/MyOwnSearchEngine/Processors/Factor.cs
+++ src/MyOwnSearchEngine/Processors/Factor.cs
@@ -1,6 +1,7 @@
 using System.Collections.Generic;
 using System.Numerics;
 using System.Text;
+using Number = System.Int32;

 namespace MyOwnSearchEngine
 {
@@ -9,22 +10,36 @@
         public string GetResult(Query query)
         {
             var integer = query.TryGetStructure<Integer>();
-            if (integer != null)
+            if (integer != null && integer.Value > -10000000 && integer.Value < 10000000)
             {
-                return GetResult(integer.Value);
+                return GetResult((int)integer.Value);
             }

             return null;
         }

-        private string GetResult(BigInteger number)
+        private string GetResult(Number number)
         {
-            number = BigInteger.Abs(number);
+            if (number < 0)
+            {
+                number = -number;
+            }

-            var factors = new List<BigInteger>();
+            if (number < 4 || number > 10000000)
+            {
+                return null;
+            }
+
+            var factors = new List<Number>();
             var bound = number / 2;
-            for (long i = 2; i <= bound; i++)
+            for (Number i = 2; i <= bound; i++)
             {
+                if (i > 3)
+                {
+                    // skip further even divisors
+                    i++;
+                }
+
                 while (number % i == 0)
                 {
                     number /= i;


One other harmonization issue for Mono.Options...

--- src/NDesk.Options/NDesk.Options/Options.cs
+++ src/NDesk.Options/NDesk.Options/Options.cs
@@ -1086,7 +1086,7 @@

 		private static int GetLineEnd (int start, int length, string description)
 		{
-			int end = Math.Min (start + length, description.Length);
+			int end = System.Math.Min (start + length, description.Length);
 			int sep = -1;
 			for (int i = start; i < end; ++i) {
 				switch (description [i]) {


Add test to ensure that NH-2151 works.

Add test to ensure that NH-2151 works.

--- src/NHibernate.Test/Linq/SelectionTests.cs
+++ src/NHibernate.Test/Linq/SelectionTests.cs
@@ -73,61 +73,61 @@
 			Assert.IsTrue(list.All(u => u.RoleName == "Admin" || u.RoleName == "User" || String.IsNullOrEmpty(u.RoleName)));
 		}

-        [Test]
-        public void CanSelectNestedAnonymousTypeWithMultipleReferences()
-        {
-            var query = from user in db.Users
-                        select new
-                        {
-                            user.Name,
-                            Enums = new
-                            {
-                                user.Enum1,
-                                user.Enum2
-                            },
-                            RoleName = user.Role.Name,
-                            RoleIsActive = (bool?) user.Role.IsActive
-                        };
-
-            var list = query.ToList();
-            Assert.AreEqual(3, list.Count);
-
-            //assert role names -- to ensure that the correct values were used to invoke constructor
-            Assert.IsTrue(list.All(u => u.RoleName == "Admin" || u.RoleName == "User" || String.IsNullOrEmpty(u.RoleName)));
-        }
-
-        [Test]
-        public void CanSelectNestedAnonymousTypeWithComponentReference()
-        {
-            var query = from user in db.Users
-                        select new
-                        {
-                            user.Name,
-                            Enums = new
-                            {
-                                user.Enum1,
-                                user.Enum2
-                            },
-                            RoleName = user.Role.Name,
-                            ComponentProperty = user.Component.Property1
-                        };
-
-            var list = query.ToList();
-            Assert.AreEqual(3, list.Count);
-
-            //assert role names -- to ensure that the correct values were used to invoke constructor
-            Assert.IsTrue(list.All(u => u.RoleName == "Admin" || u.RoleName == "User" || String.IsNullOrEmpty(u.RoleName)));
-        }
-
-		[Test]
-        public void CanSelectNestedMemberInitExpression()
+		[Test]
+		public void CanSelectNestedAnonymousTypeWithMultipleReferences()
+		{
+			var query = from user in db.Users
+						select new
+						{
+							user.Name,
+							Enums = new
+							{
+								user.Enum1,
+								user.Enum2
+							},
+							RoleName = user.Role.Name,
+							RoleIsActive = (bool?) user.Role.IsActive
+						};
+
+			var list = query.ToList();
+			Assert.AreEqual(3, list.Count);
+
+			//assert role names -- to ensure that the correct values were used to invoke constructor
+			Assert.IsTrue(list.All(u => u.RoleName == "Admin" || u.RoleName == "User" || String.IsNullOrEmpty(u.RoleName)));
+		}
+
+		[Test]
+		public void CanSelectNestedAnonymousTypeWithComponentReference()
+		{
+			var query = from user in db.Users
+						select new
+						{
+							user.Name,
+							Enums = new
+							{
+								user.Enum1,
+								user.Enum2
+							},
+							RoleName = user.Role.Name,
+							ComponentProperty = user.Component.Property1
+						};
+
+			var list = query.ToList();
+			Assert.AreEqual(3, list.Count);
+
+			//assert role names -- to ensure that the correct values were used to invoke constructor
+			Assert.IsTrue(list.All(u => u.RoleName == "Admin" || u.RoleName == "User" || String.IsNullOrEmpty(u.RoleName)));
+		}
+
+		[Test]
+		public void CanSelectNestedMemberInitExpression()
 		{
 			var query = from user in db.Users
 						select new UserDto(user.Id, user.Name)
 						{
 							InvalidLoginAttempts = user.InvalidLoginAttempts,
 							Dto2 = new UserDto2
-							           {
+									   {
 								RegisteredAt = user.RegisteredAt,
 								Enum = user.Enum2
 							},
@@ -142,7 +142,7 @@
 		}

 		[Test]
-        public void CanSelectNestedMemberInitWithinNewExpression()
+		public void CanSelectNestedMemberInitWithinNewExpression()
 		{
 			var query = from user in db.Users
 						select new
@@ -150,7 +150,7 @@
 							user.Name,
 							user.InvalidLoginAttempts,
 							Dto = new UserDto2
-							          {
+									  {
 								RegisteredAt = user.RegisteredAt,
 								Enum = user.Enum2
 							},
@@ -294,5 +294,22 @@
 			Assert.AreEqual(2, timesheets[1].EntryCount);
 			Assert.AreEqual(4, timesheets[2].EntryCount);
 		}
+
+
+		[Test]
+		public void CanSelectWrappedType()
+		{
+			//NH-2151
+			var query = from user in db.Users
+						select new Wrapper<User> { item = user, message = user.Name + " " + user.Role };
+
+			Assert.IsTrue(query.ToArray().Length > 0);
+		}
+
+		public class Wrapper<T>
+		{
+			public T item;
+			public string message;
+		}
 	}
 }


Removed Register code and fixed SqlTypeToString(BooleanSqlType)

SVN: 488784591515bd4cdaa016be4ec9b172dc4e7caf@293

--- src/NHibernate/Dialect/MsSql2000Dialect.cs
+++ src/NHibernate/Dialect/MsSql2000Dialect.cs
@@ -3,126 +3,77 @@

 using NHibernate.SqlTypes;

-namespace NHibernate.Dialect {
+namespace NHibernate.Dialect
+{
 	/// <summary>
 	/// An SQL dialect compatible with Microsoft SQL Server 2000.
 	/// </summary>
-	public class MsSql2000Dialect: Dialect {
-
-		public MsSql2000Dialect() : base() {
-
-			// ========EXACT NUMERICS==============
-			//	Integers
-			Register( DbType.Boolean, "TINYINT" ); //Sybase BIT type does not support null values
-			Register( DbType.Int16, "SMALLINT" );
-			Register( DbType.Int32, "INT" );
-			Register( DbType.Int64, "BIGINT" );
-
-			//	bit
-			Register( DbType.Byte, "TINYINT" );
-
-			// decimal & numeric
-			// TODO: figure out if this is the good way to fix the problem
-			// with exporting a DECIMAL column
-			// NUMERIC(precision, scale) has a hardcoded precision of 19, even though it can range from 1 to 38
-			// and the scale has to be 0 <= scale <= precision
-			//Register( DbType.Decimal, "NUMERIC(19,$1)" );
-			Register( DbType.Decimal, "DECIMAL(19,0)" ); // NUMERIC(19,0) is equivalent to DECIMAL(19,0)
-			Register( DbType.Decimal, 19, "DECIMAL(19, $1)");
-
-			//	money & smallmoney
-			Register (DbType.Currency, "MONEY");
-
-
-			// ========APPROXIMATE NUMERICS==============
-			//Register( DbType.Single, "FLOAT" );
-			Register( DbType.Single, "FLOAT(24)" ); //synonym for REAL
-			Register( DbType.Double, "DOUBLE PRECISION" ); //synonym for FLOAT(53)
-
-
-			// ========DATETIME & SMALLDATETIME==============
-			Register( DbType.Date, "DATETIME");
-			Register( DbType.DateTime, "DATETIME" );
-
-
-			// ========CHARACTER STRINGS==============
-			//Register( DbType.Character, "CHAR(1)" );
-			Register( DbType.AnsiStringFixedLength, "CHAR(255)");
-			Register( DbType.AnsiStringFixedLength, 8000, "CHAR($1)" );
-
-			Register( DbType.AnsiString, "VARCHAR(255)" );
-			Register( DbType.AnsiString, 8000, "VARCHAR($1)" );
-			Register( DbType.AnsiString, 2147483647, "TEXT"); // should use the IType.ClobType
-
-			// TODO: figure out how to support this - VARCHAR > 8000
-			// I think that each DbType can only be registered once??
-			//Register( DbType.AnsiString, "TEXT" );
-
-			// ========UNICODE CHARACTER STRINGS==============
-			Register( DbType.StringFixedLength, "NCHAR(255)");
-			Register( DbType.StringFixedLength, 4000, "NCHAR($1)");
-			Register( DbType.String, "NVARCHAR(255)" );
-			Register( DbType.String, 4000, "NVARCHAR($1)" );
-			Register( DbType.String, 1073741823, "NTEXT" );// should use the IType.ClobType
-
-			Register( DbType.Binary, "VARBINARY(8000)");
-			Register( DbType.Binary, 8000, "VARBINARY($1)");
-			Register( DbType.Binary, 2147483647, "IMAGE" );// should use the IType.BlobType
-
-			//Register( DbType.Timestamp, "DATETIME" );
-			//Register( DbType.VarBinary, "VARBINARY($1)" );
-
-
-
+	public class MsSql2000Dialect: Dialect
+	{
+
+		public MsSql2000Dialect() : base()
+		{
 			/*
-				getDefaultProperties().setProperty(Environment.OUTER_JOIN, "true");
-				getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
-				*/
-		}
-
-		public override string AddColumnString {
+			getDefaultProperties().setProperty(Environment.OUTER_JOIN, "true");
+			getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
+			*/
+		}
+
+		public override string AddColumnString
+		{
 			get { return "add"; }
 		}
-		public override string NullColumnString {
+		public override string NullColumnString
+		{
 			get { return " null"; }
 		}
-		public override bool QualifyIndexName {
+		public override bool QualifyIndexName
+		{
 			get { return false; }
 		}

-		public override bool SupportsForUpdate {
+		public override bool SupportsForUpdate
+		{
 			get { return false; }
 		}

-		public override bool SupportsIdentityColumns {
+		public override bool SupportsIdentityColumns
+		{
 			get { return true; }
 		}
-		public override string IdentitySelectString {
+		public override string IdentitySelectString
+		{
 			get { return "select @@identity"; }
 		}
-		public override string IdentityColumnString {
+		public override string IdentityColumnString
+		{
 			get { return "IDENTITY NOT NULL"; }
 		}

-		public override string NoColumnsInsertString {
+		public override string NoColumnsInsertString
+		{
 			get { return "DEFAULT VALUES"; }
 		}

 		[Obsolete("See the Dialect class for reason")]
-		public override bool UseNamedParameters {
+		public override bool UseNamedParameters
+		{
 			get { return true; }
 		}

 		[Obsolete("See the Dialect class for reason")]
-		public override string NamedParametersPrefix {
+		public override string NamedParametersPrefix
+		{
 			get { return "@"; }
 		}

-		private string SqlTypeToString(string name, int length) {
+		private string SqlTypeToString(string name, int length)
+		{
 			return name + "(" + length + ")";
 		}

-		private string SqlTypeToString(string name, int precision, int scale) {
+		private string SqlTypeToString(string name, int precision, int scale)
+		{
 			return name + "(" + precision + ", " + scale + ")";
 		}

@@ -168,7 +119,7 @@

 		protected override string SqlTypeToString(BooleanSqlType sqlType)
 		{
-			return "TINYINT";
+			return "BIT";
 		}

@@ -230,10 +181,12 @@
 		protected override string SqlTypeToString(StringFixedLengthSqlType sqlType)
 		{

-			if(sqlType.Length <= 4000) {
+			if(sqlType.Length <= 4000)
+			{
 				return SqlTypeToString("NCHAR", sqlType.Length);
 			}
-			else {
+			else
+			{
 				return "NTEXT"; // should use the IType.ClobType
 			}

@@ -241,10 +194,12 @@

 		protected override string SqlTypeToString(StringSqlType sqlType) {

-			if(sqlType.Length <= 4000) {
+			if(sqlType.Length <= 4000)
+			{
 				return SqlTypeToString("NVARCHAR", sqlType.Length);
 			}
-			else {
+			else
+			{
 				return "NTEXT";
 			}


removed unneeded cast

removed unneeded cast

--- src/NLog/Config/XmlLoggingConfiguration.cs
+++ src/NLog/Config/XmlLoggingConfiguration.cs
@@ -1061,9 +1061,8 @@
             {
                 var layout = kvp.Value;
                 //this value is set from xml and that's a string. Because of that, we can use SimpleLayout here.
-                var simpleLayout = layout as SimpleLayout;
-
-                if (simpleLayout != null) output = output.Replace("${" + kvp.Key + "}", simpleLayout.OriginalText);
+
+                if (layout != null) output = output.Replace("${" + kvp.Key + "}", layout.OriginalText);
             }

             return output;


revert changes in global layoutrenderer

revert changes in global layoutrenderer

--- src/NLog/LayoutRenderers/LayoutRenderer.cs
+++ src/NLog/LayoutRenderers/LayoutRenderer.cs
@@ -138,8 +138,8 @@
         /// <summary>
         /// Closes this instance.
         /// </summary>
-		internal void Close()
-		{
+        internal void Close()
+        {
             if (this.isInitialized)
             {
                 this.LoggingConfiguration = null;
@@ -148,8 +148,8 @@
             }
         }

-		internal void Render(StringBuilder builder, LogEventInfo logEvent)
-		{
+        internal void Render(StringBuilder builder, LogEventInfo logEvent)
+        {
             if (!this.isInitialized)
             {
                 this.isInitialized = true;
@@ -168,13 +168,6 @@
                 }

                 InternalLogger.Warn("Exception in layout renderer: {0}", exception);
-
-                if (LogManager.ThrowExceptions)
-                {
-                    throw;
-                }
-
-
             }
         }


Continue execution after one assembly throws an exception

--- src/NUnitTestAdapter/NUnit3TestExecutor.cs
+++ src/NUnitTestAdapter/NUnit3TestExecutor.cs
@@ -61,9 +61,9 @@
 #endif
             Initialize(runContext, frameworkHandle);

-            try
-            {
-                foreach (var source in sources)
+            foreach (var source in sources)
+            {
+                try
                 {
                     var assemblyName = source;
                     if (!Path.IsPathRooted(assemblyName))
@@ -73,18 +73,16 @@

                     RunAssembly(assemblyName, TestFilter.Empty);
                 }
-            }
-            catch (Exception ex)
-            {
-                if (ex is TargetInvocationException)
-                    ex = ex.InnerException;
-                TestLog.Error("Exception thrown executing tests", ex);
-            }
-            finally
-            {
-                TestLog.Info(string.Format("NUnit Adapter {0}: Test execution complete", AdapterVersion));
-                Unload();
-            }
+                catch (Exception ex)
+                {
+                    if (ex is TargetInvocationException)
+                        ex = ex.InnerException;
+                    TestLog.Error("Exception thrown executing tests", ex);
+                }
+            }
+
+            TestLog.Info(string.Format("NUnit Adapter {0}: Test execution complete", AdapterVersion));
+            Unload();

         }


Port the changes made to the authorization controller from the Velusia sample to Mvc.Server

--- samples/Mvc.Server/Controllers/AuthorizationController.cs
+++ samples/Mvc.Server/Controllers/AuthorizationController.cs
@@ -60,9 +60,11 @@
                 throw new InvalidOperationException("The OpenID Connect request cannot be retrieved.");

             // Retrieve the user principal stored in the authentication cookie.
-            // If it can't be extracted, redirect the user to the login page.
+            // If a max_age parameter was provided, ensure that the cookie is not too old.
+            // If the user principal can't be extracted or the cookie is too old, redirect the user to the login page.
             var result = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
-            if (result is null || !result.Succeeded)
+            if (result == null || !result.Succeeded || (request.MaxAge != null && result.Properties?.IssuedUtc != null &&
+                DateTimeOffset.UtcNow - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value)))
             {
                 // If the client application requested promptless authentication,
                 // return an error indicating that the user is not logged in.
@@ -105,31 +107,6 @@
                     properties: new AuthenticationProperties
                     {
                         RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters)
-                    });
-            }
-
-            // If a max_age parameter was provided, ensure that the cookie is not too old.
-            // If it's too old, automatically redirect the user agent to the login page.
-            if (request.MaxAge is not null && result.Properties?.IssuedUtc is not null &&
-                DateTimeOffset.UtcNow - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value))
-            {
-                if (request.HasPrompt(Prompts.None))
-                {
-                    return Forbid(
-                        authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
-                        properties: new AuthenticationProperties(new Dictionary<string, string>
-                        {
-                            [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired,
-                            [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is not logged in."
-                        }));
-                }
-
-                return Challenge(
-                    authenticationSchemes: IdentityConstants.ApplicationScheme,
-                    properties: new AuthenticationProperties
-                    {
-                        RedirectUri = Request.PathBase + Request.Path + QueryString.Create(
-                            Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList())
                     });
             }


Add a test method 'StringUtilsTest#GetLineTest'

--- UnitTest/StringUtilsTest.cs
+++ UnitTest/StringUtilsTest.cs
@@ -80,5 +80,17 @@
             Assert.AreEqual(2, strs.Length);
             StringAssert.Contains(strs[0], source);
         }
+
+        [TestMethod]
+        public void GetLineTest()
+        {
+            Assert.AreEqual(string.Empty, string.Empty.GetLine(1));
+            Assert.AreEqual("123", "123".GetLine(1));
+            Assert.AreEqual("123", "123\n".GetLine(1));
+            Assert.AreEqual(string.Empty, "123\n".GetLine(2));
+            Assert.AreEqual("123", "123\n\n456".GetLine(1));
+            Assert.AreEqual(string.Empty, "123\n\n456".GetLine(2));
+            Assert.AreEqual("456", "123\n\n456".GetLine(3));
+        }
     }
 }