Improved reading from and writing to PPU memory. It now takes into account some mirroring that was previously missing on the reads, handles wrapping on both now, and correctly fills the buffer when a read is made to the palette

--- dotnetNES.Engine/Processors/PictureProcessingUnit.cs
+++ dotnetNES.Engine/Processors/PictureProcessingUnit.cs
@@ -351,7 +351,7 @@
         /// <returns>a byte of memory</returns>
         internal byte ReadPPUMemory(int address)
         {
-            return _internalMemory[address];
+            return ReadInternalMemory(address);
         }

         /// <summary>
@@ -379,8 +379,6 @@
         /// <param name="nameTableSelect">The nametable to select</param>
         internal unsafe void DrawNametable(byte* nameTablePointer, int nameTableSelect)
         {
-
-
             // 32 Tiles Wide
             // 30 Rows Tall
             var currentPosition = 0;
@@ -462,7 +460,7 @@
         {
             if (!_internalResetFlag)
             {
-                WriteLog("Stepping PPU");
+                //WriteLog("Stepping PPU");

                 if (_nmiOccurred && _nmiOutput)
                 {
@@ -945,7 +943,9 @@
                     }
                 case 257:
                     {
+                        WriteLog("Setting Hori(V) = Hori(T)");
                         //_currentAddress = (_currentAddress & 0x7BE0) | (_temporaryAddress & 0x041F);
+
                         _nameTableAddress = 0x2000 | (_currentAddress & 0x0FFF);

                         ObjectAttributeMemoryRegister = 0;
@@ -961,6 +961,7 @@

             if (ScanLine == 261 && CycleCount > 279 && CycleCount < 305)
             {
+                WriteLog("Setting Vert(V) = Vert(T)");
                 //_currentAddress = (_currentAddress & 0x041F) | (_temporaryAddress & 0x7BE0);
             }
         }
@@ -975,12 +976,12 @@
             //if ((_currentAddress & 0x001F) == 0x001F)
             //{
             //    _currentAddress ^= 0x041F;
-            //    WriteLog(string.Format("IncrementV: Wrapping Occurred, _currentAddress is now {0}", _currentAddress));
+            //    WriteLog("IncrementH: Wrapping Occurred");
             //}
             //else
             //{
             //    _currentAddress++;
-            //    WriteLog(string.Format("IncrementV: Current Address Incremented, _currentAddress is now {0}", _currentAddress));
+            //    WriteLog("IncrementH: Current Address Incremented");
             //}

         }
@@ -991,7 +992,7 @@
             if ((_currentAddress & 0x7000) != 0x7000)
             {
                 //_currentAddress += 0x1000; // increment fine Y
-                //WriteLog(string.Format("IncrementH: Current Address Incremented, _currentAddress is now {0}", _currentAddress));
+                WriteLog(string.Format("IncrementH: Current Address Incremented, _currentAddress is now {0}", _currentAddress));
             }
             else
             {
@@ -1042,16 +1043,19 @@
                     {
                         //If the _crrent address is not a palette read, it goes into a buffer. Otherwise
                         //It is ready directly
-                        if (_currentAddress < 0x3F00)
+                        if (_currentAddress  < 0x3F00)
                         {
                             DataRegister = _ppuDataReadBuffer;
-                            _ppuDataReadBuffer = _internalMemory[_currentAddress];
+                            _ppuDataReadBuffer = ReadInternalMemory(_currentAddress);
                         }
                         else
                         {
-                            DataRegister = _internalMemory[_currentAddress];
-                            //PPU Memory Mirror fix
-                            _ppuDataReadBuffer = _internalMemory[_currentAddress];
+
+                            DataRegister = ReadInternalMemory(_currentAddress);
+
+                            //When the PPU returns a palette byte, it sets the buffer differently
+                            var tempAddress = _currentAddress & 0x2FFF;
+                            _ppuDataReadBuffer = ReadInternalMemory(tempAddress);
                         }

                         _currentAddress = (_currentAddress + _currentAddressIncrement) & 0x7FFF;
@@ -1125,24 +1129,49 @@
                 }
                 case 0x2007:
                 {
-                    //Mirroring
-                    int mirrorAddress;
-
-                    if (_currentAddress > 0x3F1F)
-                    {
-                        mirrorAddress = (_currentAddress - 0x20) & 0x3FFF;
-                    }
-                    else
-                        mirrorAddress = _currentAddress & 0x3FFF;
-
-                    _internalMemory[mirrorAddress] = DataRegister;
-
+                    WriteInternalMemory(_currentAddress, DataRegister);
                     _currentAddress = (_currentAddress + _currentAddressIncrement) & 0x7FFF;
-
-                    WriteLog(string.Format("Memory: 0x2007 write, value {0} written to address {1}  Current Address Incremented to {2}", DataRegister, mirrorAddress, _currentAddress));
-                    break;
-                }
-            }
+                    break;
+                }
+            }
+        }
+
+
+        private byte ReadInternalMemory(int originalAddress)
+        {
+            var tempAddress = originalAddress & 0x3FFF;
+
+            //Handling Wrapping in the Palette memory
+            if (tempAddress > 0x3f1f)
+            {
+                tempAddress -= 0x20;
+            }
+            //Handling wrapping in the nametable memory
+            else if (tempAddress > 0x2fff && tempAddress < 0x3f00)
+            {
+                tempAddress -= 0x1000;
+            }
+
+            return _internalMemory[tempAddress];
+        }
+
+        private void WriteInternalMemory(int originalAddress, byte value)
+        {
+            var tempAddress = originalAddress & 0x3FFF;
+
+            //Handling Wrapping in the Palette memory
+            if (tempAddress > 0x3f1f)
+            {
+                tempAddress -= 0x20;
+            }
+            //Handling wrapping in the nametable memory
+            else if (tempAddress > 0x2fff && tempAddress < 0x3f00)
+            {
+                tempAddress -= 0x1000;
+            }
+
+            WriteLog(string.Format("Memory: write, value {0} written to address {1}", value, _temporaryAddress));
+            _internalMemory[tempAddress] = value;
         }
         #endregion

@@ -1359,7 +1388,7 @@
         [Conditional("DEBUG")]
         private void WriteLog(string log)
         {
-            _logger.DebugFormat("SL: {0} P: {1} IsOdd: {2} Rend: {3} NMIOccured: {4} NMIOutput: {5} CurrentAddress: {6} {7}", ScanLine, CycleCount, _isOddFrame, _isRenderingDisabled, _nmiOccurred, _nmiOutput, _currentAddress, log);
+            _logger.DebugFormat("SL: {0} P: {1} IsOdd: {2} Rend: {3} NMIOccured: {4} NMIOutput: {5} CurrentAddress: {6} {7}", ScanLine, CycleCount, _isOddFrame, _isRenderingDisabled, _nmiOccurred, _nmiOutput, _currentAddress.ToString("X"), log);
         }
         #endregion
     }


Build up bulk payload using a dictionary instead of string

--- src/Serilog.Sinks.ElasticSearch/Sinks/ElasticSearch/ElasticSearchSink.cs
+++ src/Serilog.Sinks.ElasticSearch/Sinks/ElasticSearch/ElasticSearchSink.cs
@@ -78,42 +78,30 @@
         /// </remarks>
         protected override void EmitBatch(IEnumerable<LogEvent> events)
         {
-            var indexName = string.Format(_indexFormat, DateTime.UtcNow);
-            var items = events
-                .Select(logEvent => new Data.LogEvent(logEvent, logEvent.RenderMessage(_formatProvider)))
-                .ToList();
+			var logEvents = events.Select(e => new Data.LogEvent(e, e.RenderMessage(_formatProvider)));
+
+			if (!logEvents.Any())
+				return;

-			if (items.Any() && _client != null)
+			var indexName = string.Format(_indexFormat, DateTime.UtcNow);
+			var payload = new List<object>();
+
+			foreach (var logEvent in logEvents)
 			{
-				var bulk = new List<string>();
-				var builder = new StringBuilder();
+				var document = new Dictionary<string, object>();
+				document.Add("@timestamp", logEvent.Timestamp);
+				document.Add("messageTemplate", logEvent.MessageTemplate);
+				document.Add("level", Enum.GetName(typeof(LogEventLevel), logEvent.Level));
+				if (logEvent.Exception != null)
+					document.Add("exception", logEvent.Exception);
+				document.Add("message", logEvent.RenderedMessage);
+				document.Add("fields", logEvent.Properties);

-				foreach (var item in items)
-				{
-					builder.Append("{\"index\":{\"_index\":\"").Append(indexName).Append("\",\"_type\":\"logevent\"}}");
-					bulk.Add(builder.ToString());
-					builder.Clear();
-					builder.Append("{\"@timestamp\":").Append("\"").Append(item.Timestamp).Append("\",");
-					builder.Append("\"messageTemplate\":").Append("\"").Append(item.MessageTemplate).Append("\",");
-					builder.Append("\"level\":").Append("\"").Append(item.Level).Append("\",");
-					if (item.Exception != null)
-						builder.Append("\"exception\":").Append("\"").Append(item.Exception).Append("\",");
-					builder.Append("\"message\":").Append("\"").Append(item.RenderedMessage.Replace("\"", "\\\"")).Append("\",");
-					builder.Append("\"fields\":{");
-					for (int i = 0; i < item.Properties.Count; i++)
-					{
-						var property = item.Properties.ElementAt(i);
-						builder.Append("\"").Append(property.Key).Append("\":\"").Append(property.Value).Append("\"");
-						if (i + 1 != item.Properties.Count)
-							builder.Append(",");
-					}
-					builder.Append("}}");
-					bulk.Add(builder.ToString());
-					builder.Clear();
-				}
+				payload.Add(new { index = new { _index = indexName, _type = "logevent" } });
+				payload.Add(document);
+			}

-				_client.Bulk(bulk);
-			}
-        }
+			_client.Bulk(payload);
+		}
     }
 }


Flush only specified Redis database

Flush only specified Redis database

--- src/StackExchange.Redis.Extensions.Core/StackExchangeRedisCacheClient.cs
+++ src/StackExchange.Redis.Extensions.Core/StackExchangeRedisCacheClient.cs
@@ -623,7 +623,7 @@

 			foreach (var endpoint in endPoints)
 			{
-				db.Multiplexer.GetServer(endpoint).FlushDatabase();
+				db.Multiplexer.GetServer(endpoint).FlushDatabase(db.Database);
 			}
 		}

@@ -633,7 +633,7 @@

 			foreach (var endpoint in endPoints)
 			{
-				await db.Multiplexer.GetServer(endpoint).FlushDatabaseAsync();
+                await db.Multiplexer.GetServer(endpoint).FlushDatabaseAsync(db.Database);
 			}
 		}


Play explosion sound on player death

Play explosion sound on player death

--- Client/PlayerShip.cs
+++ Client/PlayerShip.cs
@@ -108,6 +108,7 @@
             layer = CollisionLayer.None;
             layermask = CollisionLayer.None;
             // fancy display
+            Assets.GetSound("ExplosionMedium").Play3D(world.GetPlayerShip().position, position);
             NetServer.PublishParticleEffect(ParticleEffect.Explosion, position);
         }


small refactor

small refactor

--- src/Stove.EntityFramework/EntityFramework/EfActiveTransactionProvider.cs
+++ src/Stove.EntityFramework/EntityFramework/EfActiveTransactionProvider.cs
@@ -1,9 +1,11 @@
 using System;
 using System.Data;
 using System.Data.Entity;
+using System.Reflection;

 using Autofac.Extras.IocManager;

+using Stove.Extensions;
 using Stove.Transactions;

 namespace Stove.EntityFramework
@@ -32,11 +34,9 @@
             var dbContextType = (Type)args["ContextType"];
             Type dbContextProviderType = typeof(IDbContextProvider<>).MakeGenericType(dbContextType);
             object dbContextProvider = _scopeResolver.Resolve(dbContextProviderType);
-
-            Type func = typeof(Func<>).MakeGenericType(dbContextType);
-            var getDbContextFunc = (Func<DbContext>)Delegate.CreateDelegate(func, dbContextProvider, "GetDbContext");
-
-            return getDbContextFunc();
+            MethodInfo method = dbContextProvider.GetType().GetMethod("GetDbContext");
+            var dbContext = method.Invoke(dbContextProvider, null).As<DbContext>();
+            return dbContext;
         }
     }
 }


Make the text mode remote console really work. It can now be used to send multi-word commands with proper quoting, handles arguments with spaces and allows interactive use, e.g. user creation.

--- OpenSim/ConsoleClient/ConsoleClient.cs
+++ OpenSim/ConsoleClient/ConsoleClient.cs
@@ -29,6 +29,7 @@
 using log4net;
 using System.Reflection;
 using System;
+using System.IO;
 using System.Xml;
 using System.Collections.Generic;
 using OpenSim.Server.Base;
@@ -73,9 +74,18 @@

             Requester.MakeRequest("http://"+m_Host+":"+m_Port.ToString()+"/StartSession/", String.Format("USER={0}&PASS={1}", m_User, m_Pass), LoginReply);

-            int res = m_Server.Run();
-
-            Environment.Exit(res);
+            string pidFile = serverConfig.GetString("PIDFile", String.Empty);
+
+            while (m_Server.Running)
+            {
+                System.Threading.Thread.Sleep(500);
+                // MainConsole.Instance.Prompt();
+            }
+
+            if (pidFile != String.Empty)
+                File.Delete(pidFile);
+
+            Environment.Exit(0);

             return 0;
         }
@@ -83,13 +93,14 @@
         private static void SendCommand(string module, string[] cmd)
         {
             string sendCmd = "";
+            string[] cmdlist = new string[cmd.Length - 1];
+
+            sendCmd = cmd[0];
+
             if (cmd.Length > 1)
             {
-                sendCmd = cmd[0];
-
-                Array.Copy(cmd, 1, cmd, 0, cmd.Length-1);
-                Array.Resize(ref cmd, cmd.Length-1);
-                sendCmd += "\"" + String.Join("\" \"", cmd) + "\"";
+                Array.Copy(cmd, 1, cmdlist, 0, cmd.Length - 1);
+                sendCmd += " \"" + String.Join("\" \"", cmdlist) + "\"";
             }

             Requester.MakeRequest("http://"+m_Host+":"+m_Port.ToString()+"/SessionCommand/", String.Format("ID={0}&COMMAND={1}", m_SessionID, sendCmd), CommandReply);
@@ -183,16 +194,27 @@
             while (lines.Count > 100)
                 lines.RemoveAt(0);

+            string prompt = String.Empty;
+
             foreach (string l in lines)
             {
                 string[] parts = l.Split(new char[] {':'}, 3);
                 if (parts.Length != 3)
                     continue;

-                MainConsole.Instance.Output(parts[2].Trim(), parts[1]);
-            }
+                if (parts[2].StartsWith("+++") || parts[2].StartsWith("-++"))
+                    prompt = parts[2];
+                else
+                    MainConsole.Instance.Output(parts[2].Trim(), parts[1]);
+            }
+

             Requester.MakeRequest(requestUrl, requestData, ReadResponses);
+
+            if (prompt.StartsWith("+++"))
+                MainConsole.Instance.ReadLine(prompt.Substring(3), true, true);
+            else if (prompt.StartsWith("-++"))
+                SendCommand(String.Empty, new string[] { MainConsole.Instance.ReadLine(prompt.Substring(3), false, true) });
         }

         public static void CommandReply(string requestUrl, string requestData, string replyData)


Species.cs: Make enumerator UNC first.

Species.cs: Make enumerator UNC first.

--- AIWolfLib/Species.cs
+++ AIWolfLib/Species.cs
@@ -22,17 +22,6 @@
     {
 #if JHELP
         /// <summary>
-        /// 人間
-        /// </summary>
-#else
-        /// <summary>
-        /// Human.
-        /// </summary>
-#endif
-        HUMAN = 1,
-
-#if JHELP
-        /// <summary>
         /// 不明
         /// </summary>
 #else
@@ -41,6 +30,17 @@
         /// </summary>
 #endif
         UNC,
+
+#if JHELP
+        /// <summary>
+        /// 人間
+        /// </summary>
+#else
+        /// <summary>
+        /// Human.
+        /// </summary>
+#endif
+        HUMAN,

 #if JHELP
         /// <summary>


Added notice to draw attention to Abot2.Demo for newer code demos

--- Abot.Demo/Program.cs
+++ Abot.Demo/Program.cs
@@ -9,6 +9,10 @@
     {
         static void Main(string[] args)
         {
+            /*
+             * !!!!!!!!!NOTICE!!!!!!!!: This code exercises Abot versions < 2.0.
+             * The newer versions > 2.0 have a demo in the Abot2.Demo project
+             */
             log4net.Config.XmlConfigurator.Configure();
             PrintDisclaimer();


MS-587 Transmogrified to abstract in response to PR feedback.

--- PS.Mothership.Services/Dapper.SimpleSave/Impl/BaseInsertDeleteCommand.cs
+++ PS.Mothership.Services/Dapper.SimpleSave/Impl/BaseInsertDeleteCommand.cs
@@ -1,10 +1,10 @@
 namespace Dapper.SimpleSave.Impl
 {
-    public class BaseInsertDeleteCommand : BaseCommand
+    public abstract class BaseInsertDeleteCommand : BaseCommand
     {
         private readonly BaseInsertDeleteOperation _operation;

-        public BaseInsertDeleteCommand(BaseInsertDeleteOperation operation)
+        protected BaseInsertDeleteCommand(BaseInsertDeleteOperation operation)
         {
             _operation = operation;
             TableName = operation.TableName;


Add splitter to "about" dialog, above the part about the splitter

--- AboutBSM.Designer.cs
+++ AboutBSM.Designer.cs
@@ -23,208 +23,226 @@
 		/// the contents of this method with the code editor.
 		/// </summary>
 		private void InitializeComponent() {
-			this.software_title = new System.Windows.Forms.Label();
-			this.version = new System.Windows.Forms.Label();
-			this.library_copyright = new System.Windows.Forms.Label();
-			this.textBox1 = new System.Windows.Forms.TextBox();
-			this.brawllib = new System.Windows.Forms.Label();
-			this.panel1 = new System.Windows.Forms.Panel();
-			this.panel2 = new System.Windows.Forms.Panel();
-			this.panel5 = new System.Windows.Forms.Panel();
-			this.splitter = new System.Windows.Forms.Label();
-			this.viewMspl = new System.Windows.Forms.Button();
-			this.panel3 = new System.Windows.Forms.Panel();
-			this.copyright = new System.Windows.Forms.Label();
-			this.panel4 = new System.Windows.Forms.Panel();
-			this.library_version = new System.Windows.Forms.Label();
-			this.library_title = new System.Windows.Forms.Label();
-			this.panel1.SuspendLayout();
-			this.panel2.SuspendLayout();
-			this.panel5.SuspendLayout();
-			this.panel3.SuspendLayout();
-			this.panel4.SuspendLayout();
-			this.SuspendLayout();
-			//
-			// software_title
-			//
-			this.software_title.AutoSize = true;
-			this.software_title.Dock = System.Windows.Forms.DockStyle.Left;
-			this.software_title.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-			this.software_title.Location = new System.Drawing.Point(0, 0);
-			this.software_title.Name = "software_title";
-			this.software_title.Size = new System.Drawing.Size(118, 20);
-			this.software_title.TabIndex = 0;
-			this.software_title.Text = "software_title";
-			//
-			// version
-			//
-			this.version.AutoSize = true;
-			this.version.Dock = System.Windows.Forms.DockStyle.Right;
-			this.version.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-			this.version.Location = new System.Drawing.Point(326, 0);
-			this.version.Name = "version";
-			this.version.Size = new System.Drawing.Size(66, 20);
-			this.version.TabIndex = 1;
-			this.version.Text = "version";
-			this.version.TextAlign = System.Drawing.ContentAlignment.TopRight;
-			//
-			// library_copyright
-			//
-			this.library_copyright.AutoSize = true;
-			this.library_copyright.Dock = System.Windows.Forms.DockStyle.Top;
-			this.library_copyright.Location = new System.Drawing.Point(0, 0);
-			this.library_copyright.Name = "library_copyright";
-			this.library_copyright.Padding = new System.Windows.Forms.Padding(0, 0, 0, 4);
-			this.library_copyright.Size = new System.Drawing.Size(83, 17);
-			this.library_copyright.TabIndex = 3;
-			this.library_copyright.Text = "library_copyright";
-			//
-			// textBox1
-			//
-			this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.textBox1.Location = new System.Drawing.Point(0, 17);
-			this.textBox1.Multiline = true;
-			this.textBox1.Name = "textBox1";
-			this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
-			this.textBox1.Size = new System.Drawing.Size(392, 127);
-			this.textBox1.TabIndex = 4;
-			//
-			// brawllib
-			//
-			this.brawllib.Dock = System.Windows.Forms.DockStyle.Bottom;
-			this.brawllib.Location = new System.Drawing.Point(0, 144);
-			this.brawllib.Name = "brawllib";
-			this.brawllib.Size = new System.Drawing.Size(392, 32);
-			this.brawllib.TabIndex = 5;
-			this.brawllib.Text = "brawllib";
-			this.brawllib.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
-			//
-			// panel1
-			//
-			this.panel1.Controls.Add(this.version);
-			this.panel1.Controls.Add(this.software_title);
-			this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
-			this.panel1.Location = new System.Drawing.Point(0, 0);
-			this.panel1.Name = "panel1";
-			this.panel1.Size = new System.Drawing.Size(392, 24);
-			this.panel1.TabIndex = 5;
-			//
-			// panel2
-			//
-			this.panel2.Controls.Add(this.textBox1);
-			this.panel2.Controls.Add(this.brawllib);
-			this.panel2.Controls.Add(this.library_copyright);
-			this.panel2.Controls.Add(this.panel5);
-			this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.panel2.Location = new System.Drawing.Point(0, 57);
-			this.panel2.Name = "panel2";
-			this.panel2.Size = new System.Drawing.Size(392, 208);
-			this.panel2.TabIndex = 6;
-			//
-			// panel5
-			//
-			this.panel5.Controls.Add(this.splitter);
-			this.panel5.Controls.Add(this.viewMspl);
-			this.panel5.Dock = System.Windows.Forms.DockStyle.Bottom;
-			this.panel5.Location = new System.Drawing.Point(0, 176);
-			this.panel5.Name = "panel5";
-			this.panel5.Size = new System.Drawing.Size(392, 32);
-			this.panel5.TabIndex = 7;
-			//
-			// splitter
-			//
-			this.splitter.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.splitter.Location = new System.Drawing.Point(0, 0);
-			this.splitter.Name = "splitter";
-			this.splitter.Size = new System.Drawing.Size(317, 32);
-			this.splitter.TabIndex = 6;
-			this.splitter.Text = "splitter";
-			this.splitter.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
-			//
-			// viewMspl
-			//
-			this.viewMspl.Dock = System.Windows.Forms.DockStyle.Right;
-			this.viewMspl.Location = new System.Drawing.Point(317, 0);
-			this.viewMspl.Name = "viewMspl";
-			this.viewMspl.Size = new System.Drawing.Size(75, 32);
-			this.viewMspl.TabIndex = 7;
-			this.viewMspl.Text = "View MS-PL";
-			this.viewMspl.UseVisualStyleBackColor = true;
-			this.viewMspl.Click += new System.EventHandler(this.viewMspl_Click);
-			//
-			// panel3
-			//
-			this.panel3.Controls.Add(this.copyright);
-			this.panel3.Dock = System.Windows.Forms.DockStyle.Top;
-			this.panel3.Location = new System.Drawing.Point(0, 24);
-			this.panel3.Name = "panel3";
-			this.panel3.Size = new System.Drawing.Size(392, 16);
-			this.panel3.TabIndex = 6;
-			//
-			// copyright
-			//
-			this.copyright.AutoSize = true;
-			this.copyright.Dock = System.Windows.Forms.DockStyle.Left;
-			this.copyright.Location = new System.Drawing.Point(0, 0);
-			this.copyright.Name = "copyright";
-			this.copyright.Size = new System.Drawing.Size(50, 13);
-			this.copyright.TabIndex = 0;
-			this.copyright.Text = "copyright";
-			//
-			// panel4
-			//
-			this.panel4.Controls.Add(this.library_version);
-			this.panel4.Controls.Add(this.library_title);
-			this.panel4.Dock = System.Windows.Forms.DockStyle.Top;
-			this.panel4.Location = new System.Drawing.Point(0, 40);
-			this.panel4.Name = "panel4";
-			this.panel4.Size = new System.Drawing.Size(392, 17);
-			this.panel4.TabIndex = 7;
-			//
-			// library_version
-			//
-			this.library_version.AutoSize = true;
-			this.library_version.Dock = System.Windows.Forms.DockStyle.Right;
-			this.library_version.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-			this.library_version.Location = new System.Drawing.Point(276, 0);
-			this.library_version.Name = "library_version";
-			this.library_version.Size = new System.Drawing.Size(116, 17);
-			this.library_version.TabIndex = 1;
-			this.library_version.Text = "library_version";
-			this.library_version.TextAlign = System.Drawing.ContentAlignment.TopRight;
-			//
-			// library_title
-			//
-			this.library_title.AutoSize = true;
-			this.library_title.Dock = System.Windows.Forms.DockStyle.Left;
-			this.library_title.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-			this.library_title.Location = new System.Drawing.Point(0, 0);
-			this.library_title.Name = "library_title";
-			this.library_title.Size = new System.Drawing.Size(85, 16);
-			this.library_title.TabIndex = 0;
-			this.library_title.Text = "library_title";
-			//
-			// AboutBSM
-			//
-			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-			this.ClientSize = new System.Drawing.Size(392, 265);
-			this.Controls.Add(this.panel2);
-			this.Controls.Add(this.panel4);
-			this.Controls.Add(this.panel3);
-			this.Controls.Add(this.panel1);
-			this.Name = "AboutBSM";
-			this.Text = "About";
-			this.panel1.ResumeLayout(false);
-			this.panel1.PerformLayout();
-			this.panel2.ResumeLayout(false);
-			this.panel2.PerformLayout();
-			this.panel5.ResumeLayout(false);
-			this.panel3.ResumeLayout(false);
-			this.panel3.PerformLayout();
-			this.panel4.ResumeLayout(false);
-			this.panel4.PerformLayout();
-			this.ResumeLayout(false);
+            this.software_title = new System.Windows.Forms.Label();
+            this.version = new System.Windows.Forms.Label();
+            this.library_copyright = new System.Windows.Forms.Label();
+            this.textBox1 = new System.Windows.Forms.TextBox();
+            this.brawllib = new System.Windows.Forms.Label();
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.panel2 = new System.Windows.Forms.Panel();
+            this.collapsibleSplitter1 = new BrawlManagerLib.CollapsibleSplitter();
+            this.panel5 = new System.Windows.Forms.Panel();
+            this.splitter = new System.Windows.Forms.Label();
+            this.viewMspl = new System.Windows.Forms.Button();
+            this.panel3 = new System.Windows.Forms.Panel();
+            this.copyright = new System.Windows.Forms.Label();
+            this.panel4 = new System.Windows.Forms.Panel();
+            this.library_version = new System.Windows.Forms.Label();
+            this.library_title = new System.Windows.Forms.Label();
+            this.panel1.SuspendLayout();
+            this.panel2.SuspendLayout();
+            this.panel5.SuspendLayout();
+            this.panel3.SuspendLayout();
+            this.panel4.SuspendLayout();
+            this.SuspendLayout();
+            //
+            // software_title
+            //
+            this.software_title.AutoSize = true;
+            this.software_title.Dock = System.Windows.Forms.DockStyle.Left;
+            this.software_title.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.software_title.Location = new System.Drawing.Point(0, 0);
+            this.software_title.Name = "software_title";
+            this.software_title.Size = new System.Drawing.Size(118, 20);
+            this.software_title.TabIndex = 0;
+            this.software_title.Text = "software_title";
+            //
+            // version
+            //
+            this.version.AutoSize = true;
+            this.version.Dock = System.Windows.Forms.DockStyle.Right;
+            this.version.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.version.Location = new System.Drawing.Point(326, 0);
+            this.version.Name = "version";
+            this.version.Size = new System.Drawing.Size(66, 20);
+            this.version.TabIndex = 1;
+            this.version.Text = "version";
+            this.version.TextAlign = System.Drawing.ContentAlignment.TopRight;
+            //
+            // library_copyright
+            //
+            this.library_copyright.AutoSize = true;
+            this.library_copyright.Dock = System.Windows.Forms.DockStyle.Top;
+            this.library_copyright.Location = new System.Drawing.Point(0, 0);
+            this.library_copyright.Name = "library_copyright";
+            this.library_copyright.Padding = new System.Windows.Forms.Padding(0, 0, 0, 4);
+            this.library_copyright.Size = new System.Drawing.Size(83, 17);
+            this.library_copyright.TabIndex = 3;
+            this.library_copyright.Text = "library_copyright";
+            //
+            // textBox1
+            //
+            this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.textBox1.Location = new System.Drawing.Point(0, 17);
+            this.textBox1.Multiline = true;
+            this.textBox1.Name = "textBox1";
+            this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.textBox1.Size = new System.Drawing.Size(392, 119);
+            this.textBox1.TabIndex = 4;
+            //
+            // brawllib
+            //
+            this.brawllib.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.brawllib.Location = new System.Drawing.Point(0, 136);
+            this.brawllib.Name = "brawllib";
+            this.brawllib.Size = new System.Drawing.Size(392, 32);
+            this.brawllib.TabIndex = 5;
+            this.brawllib.Text = "brawllib";
+            this.brawllib.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+            //
+            // panel1
+            //
+            this.panel1.Controls.Add(this.version);
+            this.panel1.Controls.Add(this.software_title);
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
+            this.panel1.Location = new System.Drawing.Point(0, 0);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(392, 24);
+            this.panel1.TabIndex = 5;
+            //
+            // panel2
+            //
+            this.panel2.Controls.Add(this.textBox1);
+            this.panel2.Controls.Add(this.brawllib);
+            this.panel2.Controls.Add(this.library_copyright);
+            this.panel2.Controls.Add(this.collapsibleSplitter1);
+            this.panel2.Controls.Add(this.panel5);
+            this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.panel2.Location = new System.Drawing.Point(0, 57);
+            this.panel2.Name = "panel2";
+            this.panel2.Size = new System.Drawing.Size(392, 208);
+            this.panel2.TabIndex = 6;
+            //
+            // collapsibleSplitter1
+            //
+            this.collapsibleSplitter1.AnimationDelay = 20;
+            this.collapsibleSplitter1.AnimationStep = 20;
+            this.collapsibleSplitter1.BorderStyle3D = System.Windows.Forms.Border3DStyle.Flat;
+            this.collapsibleSplitter1.ControlToHide = this.panel5;
+            this.collapsibleSplitter1.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.collapsibleSplitter1.ExpandParentForm = false;
+            this.collapsibleSplitter1.Location = new System.Drawing.Point(0, 168);
+            this.collapsibleSplitter1.Name = "collapsibleSplitter1";
+            this.collapsibleSplitter1.Size = new System.Drawing.Size(392, 8);
+            this.collapsibleSplitter1.TabIndex = 8;
+            this.collapsibleSplitter1.TabStop = false;
+            this.collapsibleSplitter1.UseAnimations = false;
+            this.collapsibleSplitter1.VisualStyle = BrawlManagerLib.VisualStyles.Mozilla;
+            //
+            // panel5
+            //
+            this.panel5.Controls.Add(this.splitter);
+            this.panel5.Controls.Add(this.viewMspl);
+            this.panel5.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.panel5.Location = new System.Drawing.Point(0, 176);
+            this.panel5.Name = "panel5";
+            this.panel5.Size = new System.Drawing.Size(392, 32);
+            this.panel5.TabIndex = 7;
+            //
+            // splitter
+            //
+            this.splitter.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.splitter.Location = new System.Drawing.Point(0, 0);
+            this.splitter.Name = "splitter";
+            this.splitter.Size = new System.Drawing.Size(317, 32);
+            this.splitter.TabIndex = 6;
+            this.splitter.Text = "splitter";
+            this.splitter.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+            //
+            // viewMspl
+            //
+            this.viewMspl.Dock = System.Windows.Forms.DockStyle.Right;
+            this.viewMspl.Location = new System.Drawing.Point(317, 0);
+            this.viewMspl.Name = "viewMspl";
+            this.viewMspl.Size = new System.Drawing.Size(75, 32);
+            this.viewMspl.TabIndex = 7;
+            this.viewMspl.Text = "View MS-PL";
+            this.viewMspl.UseVisualStyleBackColor = true;
+            this.viewMspl.Click += new System.EventHandler(this.viewMspl_Click);
+            //
+            // panel3
+            //
+            this.panel3.Controls.Add(this.copyright);
+            this.panel3.Dock = System.Windows.Forms.DockStyle.Top;
+            this.panel3.Location = new System.Drawing.Point(0, 24);
+            this.panel3.Name = "panel3";
+            this.panel3.Size = new System.Drawing.Size(392, 16);
+            this.panel3.TabIndex = 6;
+            //
+            // copyright
+            //
+            this.copyright.AutoSize = true;
+            this.copyright.Dock = System.Windows.Forms.DockStyle.Left;
+            this.copyright.Location = new System.Drawing.Point(0, 0);
+            this.copyright.Name = "copyright";
+            this.copyright.Size = new System.Drawing.Size(50, 13);
+            this.copyright.TabIndex = 0;
+            this.copyright.Text = "copyright";
+            //
+            // panel4
+            //
+            this.panel4.Controls.Add(this.library_version);
+            this.panel4.Controls.Add(this.library_title);
+            this.panel4.Dock = System.Windows.Forms.DockStyle.Top;
+            this.panel4.Location = new System.Drawing.Point(0, 40);
+            this.panel4.Name = "panel4";
+            this.panel4.Size = new System.Drawing.Size(392, 17);
+            this.panel4.TabIndex = 7;
+            //
+            // library_version
+            //
+            this.library_version.AutoSize = true;
+            this.library_version.Dock = System.Windows.Forms.DockStyle.Right;
+            this.library_version.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.library_version.Location = new System.Drawing.Point(276, 0);
+            this.library_version.Name = "library_version";
+            this.library_version.Size = new System.Drawing.Size(116, 17);
+            this.library_version.TabIndex = 1;
+            this.library_version.Text = "library_version";
+            this.library_version.TextAlign = System.Drawing.ContentAlignment.TopRight;
+            //
+            // library_title
+            //
+            this.library_title.AutoSize = true;
+            this.library_title.Dock = System.Windows.Forms.DockStyle.Left;
+            this.library_title.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.library_title.Location = new System.Drawing.Point(0, 0);
+            this.library_title.Name = "library_title";
+            this.library_title.Size = new System.Drawing.Size(85, 16);
+            this.library_title.TabIndex = 0;
+            this.library_title.Text = "library_title";
+            //
+            // AboutBSM
+            //
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(392, 265);
+            this.Controls.Add(this.panel2);
+            this.Controls.Add(this.panel4);
+            this.Controls.Add(this.panel3);
+            this.Controls.Add(this.panel1);
+            this.Name = "AboutBSM";
+            this.Text = "About";
+            this.panel1.ResumeLayout(false);
+            this.panel1.PerformLayout();
+            this.panel2.ResumeLayout(false);
+            this.panel2.PerformLayout();
+            this.panel5.ResumeLayout(false);
+            this.panel3.ResumeLayout(false);
+            this.panel3.PerformLayout();
+            this.panel4.ResumeLayout(false);
+            this.panel4.PerformLayout();
+            this.ResumeLayout(false);

 		}

@@ -245,5 +263,6 @@
 		private System.Windows.Forms.Label splitter;
 		private System.Windows.Forms.Panel panel5;
 		private System.Windows.Forms.Button viewMspl;
+        private CollapsibleSplitter collapsibleSplitter1;
 	}
 }


For SMF format 0, simply run track merger and get total time from it.

--- lib/base/SMF.cs
+++ lib/base/SMF.cs
@@ -41,7 +41,7 @@
 		public int GetTotalPlayTimeMilliseconds ()
 		{
 			if (Format != 0)
-				throw new NotSupportedException ("Format 1 is not suitable to compute total play time within a song");
+				return SmfTrackMerger.Merge (this).GetTotalPlayTimeMilliseconds ();
 			return GetTotalPlayTimeMilliseconds (Tracks [0].Messages, DeltaTimeSpec);
 		}


TraderHelper. ToReadableString

TraderHelper. ToReadableString


Rebuilding connection don't log warning, that's normal fallback.

--- MagicalCryptoWallet/TorSocks5/TorHttpClient.cs
+++ MagicalCryptoWallet/TorSocks5/TorHttpClient.cs
@@ -73,7 +73,7 @@
 				}
 				catch (Exception ex)
 				{
-					Logger.LogWarning<TorHttpClient>(ex);
+					Logger.LogDebug<TorHttpClient>(ex);

 					TorSocks5Client?.Dispose(); // rebuild the connection and retry
 					TorSocks5Client = null;


Remove debugging traces

Remove debugging traces

--- Api/ApiConnection.cs
+++ Api/ApiConnection.cs
@@ -89,9 +89,7 @@
                 Client.Authenticator = new HttpBasicAuthenticator(_userId, hash);

                 // Execute the authenticated REST API Call
-                Log.Trace("Api.ApiConnection.TryRequest(): Request: " + request.Resource);
                 var restsharpResponse = Client.Execute(request);
-                Log.Trace("Api.ApiConnection.TryRequest(): ResponseStatus: " + restsharpResponse.ResponseStatus);

                 // Use custom converter for deserializing live results data
                 JsonConvert.DefaultSettings = () => new JsonSerializerSettings
@@ -102,7 +100,7 @@
                 //Verify success
                 if (restsharpResponse.ErrorException != null)
                 {
-                    Log.Error("Api.ApiConnection.TryRequest(): Failed to make REST request. Error: " + restsharpResponse.ErrorException);
+                    Log.Error(restsharpResponse.ErrorException);
                     result = null;
                     return false;
                 }


Can now control only 1 player at a time using Keyboard. Press TAB to switch between players.

--- Blink/Blink/Game1.cs
+++ Blink/Blink/Game1.cs
@@ -1,13 +1,17 @@
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Input;
-using Blink.Classes;
+using Blink.Classes;
+using System;

 namespace Blink
 {
     /// <summary>
     /// This is the main type for your game.
     /// </summary>
+
+    enum PlayerKeys {Player1, Player2, Player3, Player4}
+
     public class Game1 : Game
     {
         GraphicsDeviceManager graphics;
@@ -15,7 +19,13 @@
         PlayerClass player1;
         PlayerClass player2;
         PlayerClass player3;
-        PlayerClass player4;
+        PlayerClass player4;
+        PlayerKeys currPlayer;
+        KeyboardState oldState;
+        KeyboardState player1State;
+        KeyboardState player2State;
+        KeyboardState player3State;
+        KeyboardState player4State;
         Map map1;
         float GRAVITY = 0.1f;

@@ -40,7 +50,8 @@
             player2 = new PlayerClass();
             player3 = new PlayerClass();
             player4 = new PlayerClass();
-            map1 = new Map();
+            map1 = new Map();
+            currPlayer = PlayerKeys.Player1;

             base.Initialize();
         }
@@ -86,16 +97,58 @@
         /// </summary>
         /// <param name="gameTime">Provides a snapshot of timing values.</param>
         protected override void Update(GameTime gameTime)
-        {
+        {
+            KeyboardState currState = Keyboard.GetState();
             if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
-                Exit();
+                Exit();
+            // Press TAB to change player if using keyboard. *** For Testing Purposes Only ***
+            if (currState.IsKeyDown(Keys.Tab) && oldState != currState)
+            {
+                switch ((int)currPlayer)
+                {
+                    case 0:
+                        currPlayer = PlayerKeys.Player2;
+                        break;
+
+                    case 1:
+                        currPlayer = PlayerKeys.Player3;
+                        break;
+
+                    case 2:
+                        currPlayer = PlayerKeys.Player4;
+                        break;
+
+                    case 3:
+                        currPlayer = PlayerKeys.Player1;
+                        break;
+                }
+                //Switches to the next player
+            }
+            if (currPlayer == PlayerKeys.Player1)
+            {
+                player1State = Keyboard.GetState();
+            }
+
+            if (currPlayer == PlayerKeys.Player2)
+            {
+                player2State = Keyboard.GetState();
+            }
+
+            if (currPlayer == PlayerKeys.Player3)
+            {
+                player3State = Keyboard.GetState();
+            }
+            if (currPlayer == PlayerKeys.Player4)
+            {
+                player4State = Keyboard.GetState();
+            }
+            //End of TAB code. Can now only control one player at a time using keyboard.

-            // TODO: Add your update logic here
-            player1.Update(Keyboard.GetState(), GamePad.GetState(PlayerIndex.One));
-            player2.Update(Keyboard.GetState(), GamePad.GetState(PlayerIndex.Two));
-            player3.Update(Keyboard.GetState(), GamePad.GetState(PlayerIndex.Three));
-            player4.Update(Keyboard.GetState(), GamePad.GetState(PlayerIndex.Four));
-
+            player1.Update(player1State, GamePad.GetState(PlayerIndex.One));
+            player2.Update(player2State, GamePad.GetState(PlayerIndex.Two));
+            player3.Update(player3State, GamePad.GetState(PlayerIndex.Three));
+            player4.Update(player4State, GamePad.GetState(PlayerIndex.Four));
+            oldState = currState;
             base.Update(gameTime);
         }


Renaming saveController param to isNew, Added more log

--- zwavelib/ZWaveInterface.cs
+++ zwavelib/ZWaveInterface.cs
@@ -75,7 +75,7 @@
             return CreateController(port, true);
         }

-        internal bool CreateController(int port, bool saveController = false)
+        internal bool CreateController(int port, bool isNew = false)
         {
             bool result = false;
             Logger.Info("Creating Controller on port: " + port);
@@ -87,22 +87,24 @@
             }

             //Store Controller
-            if (saveController)
-            {
+            if (isNew)
+            {
+                Logger.Info("Saving new controller on port " + port);
                 _registeredControllers.StoreString(port.ToString(), port.ToString());
                 DataStore.Save();
-            }
-
-
-
+                Logger.Info("Saved new controller on port " + port);
+            }
+
+            Logger.Info("Trying to start a controller on port " + port);
             bool mngResult = _mng.AddDriver(@"\\.\COM" + port, ZWControllerInterface.Serial);
             if (mngResult)
             {
+                Logger.Info("Tryed to start a controller on port " + port + " was successfull");
                 //TODO: Set node to initializing
                 //Create new node

-                Logger.Info("Controller created on port: " + port);
+                Logger.Info("Controller created on port " + port);
                 result = true;
             }
             else
@@ -110,7 +112,7 @@
                 //TODO : SET NODE TO ERROR
                 //Create new node

-                Logger.Info("Cannot create Controller on port: " + port);
+                Logger.Info("Cannot create Controller on port " + port);
             }
             return result;
         }


Small missing fix for command refactor

Small missing fix for command refactor

--- zwavelib/ZWaveInterface.cs
+++ zwavelib/ZWaveInterface.cs
@@ -2,7 +2,6 @@
 using OHM.RAL;
 using OHM.Logger;
 using OHM.Nodes;
-using OHM.SYS;
 using OpenZWaveDotNet;
 using System;
 using System.Collections.Generic;
@@ -496,7 +495,7 @@
             else
             {
                 //Create new node
-                var ctl = new ZWaveController(@"\\.\COM" + port, @"\\.\COM" + port, this, this.Logger, NodeStates.fatal);
+                var ctl = new ZWaveController("COM" + port, "COM" + port, this, this.Logger, NodeStates.fatal);
                 this.AddChild(ctl);
                 this._runningControllers.Add(@"\\.\COM" + port, ctl);


Fixed wrong exception type

Fixed wrong exception type

--- src/Client.cs
+++ src/Client.cs
@@ -134,7 +134,7 @@
                     id = context.Session.SessionID;
                 }
             }
-            catch (HttpException ex)
+            catch (Exception ex)
             {
                 System.Diagnostics.Trace.WriteLine("Error retrieving SessionId {0}", ex.Message);
             }


reorganized extension method in root namespace

--- src/Line3D.cs
+++ src/Line3D.cs
@@ -27,228 +27,244 @@
 using System.Linq;
 using SearchAThing.Core;
 using static System.Math;
-
-namespace SearchAThing.Sci
+using SearchAThing.Sci;
+
+namespace SearchAThing
 {

-    public enum Line3DConstructMode { PointAndVector };
-
-    public class Line3D
+    public static partial class Extensions
     {
-        public static Line3D XAxisLine = new Line3D(Vector3D.Zero, Vector3D.XAxis);
-        public static Line3D YAxisLine = new Line3D(Vector3D.Zero, Vector3D.YAxis);
-        public static Line3D ZAxisLine = new Line3D(Vector3D.Zero, Vector3D.ZAxis);
-
-        public Vector3D From { get; private set; }
-        public Vector3D V { get; private set; }
-        public Vector3D To { get { return From + V; } }
-
-        public Line3D(Vector3D from, Vector3D to)
+
+        public static netDxf.Entities.Line ToDxfLine(this Line3D line3d)
         {
-            From = from;
-            V = to - from;
+            return new netDxf.Entities.Line(line3d.From.ToVector3(), line3d.To.ToVector3());
         }

-        public Line3D(Vector3D from, Vector3D v, Line3DConstructMode mode)
+    }
+
+    namespace Sci
+    {
+
+        public enum Line3DConstructMode { PointAndVector };
+
+        public class Line3D
         {
-            From = from;
-            V = v;
+            public static Line3D XAxisLine = new Line3D(Vector3D.Zero, Vector3D.XAxis);
+            public static Line3D YAxisLine = new Line3D(Vector3D.Zero, Vector3D.YAxis);
+            public static Line3D ZAxisLine = new Line3D(Vector3D.Zero, Vector3D.ZAxis);
+
+            public Vector3D From { get; private set; }
+            public Vector3D V { get; private set; }
+            public Vector3D To { get { return From + V; } }
+
+            public Line3D(Vector3D from, Vector3D to)
+            {
+                From = from;
+                V = to - from;
+            }
+
+            public Line3D(Vector3D from, Vector3D v, Line3DConstructMode mode)
+            {
+                From = from;
+                V = v;
+            }
+
+            public double Length { get { return V.Length; } }
+
+            /// <summary>
+            /// Infinite line contains point.
+            /// Note: tol must be Constant.NormalizedLengthTolerance
+            /// if comparing normalized vectors
+            /// </summary>
+            public bool LineContainsPoint(double tol, double x, double y, double z, bool segmentMode = false)
+            {
+                return LineContainsPoint(tol, new Vector3D(x, y, z), segmentMode);
+            }
+
+            /// <summary>
+            /// Infinite line contains point.
+            /// Note: tol must be Constant.NormalizedLengthTolerance
+            /// if comparing normalized vectors
+            /// </summary>
+            public bool LineContainsPoint(double tol, Vector3D p, bool segmentMode = false)
+            {
+                // line contains given point if there is a scalar s
+                // for which p = From + s * V
+
+                var s = 0.0;
+
+                // to find out the scalar we need to test the first non null component
+                if (!(V.X.EqualsTol(tol, 0))) s = (p.X - From.X) / V.X;
+                else if (!(V.Y.EqualsTol(tol, 0))) s = (p.Y - From.Y) / V.Y;
+                else if (!(V.Z.EqualsTol(tol, 0))) s = (p.Z - From.Z) / V.Z;
+
+                if (segmentMode)
+                {
+                    // s is the scalar of V vector that runs From->To
+                    if (!(s >= 0.0 && s <= 1.0)) return false;
+                }
+
+                return p.EqualsTol(tol, From.X + s * V.X, From.Y + s * V.Y, From.Z + s * V.Z);
+            }
+
+            /// <summary>
+            /// Finite segment contains point.
+            /// Note: tol must be Constant.NormalizedLengthTolerance
+            /// if comparing normalized vectors
+            /// </summary>
+            public bool SegmentContainsPoint(double tol, Vector3D p)
+            {
+                return LineContainsPoint(tol, p, segmentMode: true);
+            }
+
+            /// <summary>
+            /// Finite segment contains point.
+            /// Note: tol must be Constant.NormalizedLengthTolerance
+            /// if comparing normalized vectors
+            /// </summary>
+            public bool SegmentContainsPoint(double tol, double x, double y, double z)
+            {
+                return LineContainsPoint(tol, x, y, z, segmentMode: true);
+            }
+
+            /// <summary>
+            /// Find intersection of two 3d lines
+            /// </summary>
+            public Vector3D Intersect(double tol, Line3D other)
+            {
+                var f1x = From.X;
+                var f1y = From.Y;
+                var f1z = From.Z;
+
+                var v1x = V.X;
+                var v1y = V.Y;
+                var v1z = V.Z;
+
+                var f2x = other.From.X;
+                var f2y = other.From.Y;
+                var f2z = other.From.Z;
+
+                var v2x = other.V.X;
+                var v2y = other.V.Y;
+                var v2z = other.V.Z;
+
+                // this line  : F + alpha * V
+                // other line : other.F + beta * V
+                //
+                // i = { F + alpha * V == other.F + beta * V }
+                //   = { F1 + alpha * V1 == F2 + beta * V2 }
+                //
+                // i =
+                //   f1x + alpha * v1x == f2x + beta * v2x &&
+                //   f1y + alpha * v1y == f2y + beta * v2y &&
+                //   f1z + alpha * v1z == f2z + beta * v2z
+
+                // XY
+                //   f1x + alpha * v1x == f2x + beta * v2x &&
+                //   f1y + alpha * v1y == f2y + beta * v2y
+                {
+                    var alpha_denom = (v1y * v2x - v1x * v2y);
+                    var beta_denom = (v1y * v2x - v1x * v2y);
+
+                    if (!alpha_denom.EqualsTol(tol, 0) && !beta_denom.EqualsTol(tol, 0))
+                    {
+                        var alpha = -(f1y * v2x - f2y * v2x - f1x * v2y + f2x * v2y) / alpha_denom;
+                        var beta = -(f1y * v1x - f2y * v1x - f1x * v1y + f2x * v1y) / beta_denom;
+
+                        var i = From + alpha * V;
+
+                        if (i.EqualsTol(tol, other.From + beta * other.V)) return i;
+                    }
+                }
+
+                // XZ
+                //   f1x + alpha * v1x == f2x + beta * v2x &&
+                //   f1z + alpha * v1z == f2z + beta * v2z
+                {
+                    var alpha_denom = (v1z * v2x - v1x * v2z);
+                    var beta_denom = (v1z * v2x - v1x * v2z);
+
+                    if (!alpha_denom.EqualsTol(tol, 0) && !beta_denom.EqualsTol(tol, 0))
+                    {
+                        var alpha = -(f1z * v2x - f2z * v2x - f1x * v2z + f2x * v2z) / alpha_denom;
+                        var beta = -(f1z * v1x - f2z * v1x - f1x * v1z + f2x * v1z) / beta_denom;
+
+                        var i = From + alpha * V;
+
+                        if (i.EqualsTol(tol, other.From + beta * other.V)) return i;
+                    }
+                }
+
+                // YZ
+                //   f1y + alpha * v1y == f2y + beta * v2y &&
+                //   f1z + alpha * v1z == f2z + beta * v2z
+                {
+                    var alpha_denom = (v1z * v2y - v1y * v2z);
+                    var beta_denom = (v1z * v2y - v1y * v2z);
+
+                    if (!alpha_denom.EqualsTol(tol, 0) && !beta_denom.EqualsTol(tol, 0))
+                    {
+                        var alpha = -(f1z * v2y - f2z * v2y - f1y * v2z + f2y * v2z) / alpha_denom;
+                        var beta = -(f1z * v1y - f2z * v1y - f1y * v1z + f2y * v1z) / beta_denom;
+
+                        var i = From + alpha * V;
+
+                        if (i.EqualsTol(tol, other.From + beta * other.V)) return i;
+                    }
+                }
+
+                // no intersection
+
+                return null;
+            }
+
+            public Line3D Perpendicular(double tol, Vector3D p)
+            {
+                if (LineContainsPoint(tol, p)) return null;
+
+                return new Line3D(p, p.Project(V));
+            }
+
+            public bool Colinear(double tol, Line3D other)
+            {
+                return LineContainsPoint(tol, other.From) && LineContainsPoint(tol, other.To);
+            }
+
+            public bool IsParallelTo(double tol, Plane3D plane)
+            {
+                return V.IsParallelTo(tol, plane.CS.BaseX) && V.IsParallelTo(tol, plane.CS.BaseY);
+            }
+
+            /// <summary>
+            /// returns null if this line is parallel to the plane,
+            /// the intersection point otherwise
+            /// </summary>
+            public Vector3D Intersect(double tol, Plane3D plane)
+            {
+                if (IsParallelTo(tol, plane)) return null;
+
+                // O = plane.Origin    Vx = plane.CS.BaseX    Vy = plane.CS.BaseY
+                //
+                // plane : O + alpha * Vx + beta * Vy
+                // line  : From + gamma * V
+                //
+                // => m:{ alpha * Vx + beta * Vy - gamma * V } * s = n:{ From - O }
+
+                var m = Matrix3D.FromVectorsAsColumns(plane.CS.BaseX, plane.CS.BaseY, -V);
+                var n = From - plane.CS.Origin;
+                var s = m.Solve(n);
+
+                return From + s.Z * V;
+            }
+            public Vector3D MidPoint { get { return (From + To) / 2; } }
+
+            public override string ToString()
+            {
+                return $"{From}-{To}";
+            }
+
         }

-        public double Length { get { return V.Length; } }
-
-        /// <summary>
-        /// Infinite line contains point.
-        /// Note: tol must be Constant.NormalizedLengthTolerance
-        /// if comparing normalized vectors
-        /// </summary>
-        public bool LineContainsPoint(double tol, double x, double y, double z, bool segmentMode = false)
-        {
-            return LineContainsPoint(tol, new Vector3D(x, y, z), segmentMode);
-        }
-
-        /// <summary>
-        /// Infinite line contains point.
-        /// Note: tol must be Constant.NormalizedLengthTolerance
-        /// if comparing normalized vectors
-        /// </summary>
-        public bool LineContainsPoint(double tol, Vector3D p, bool segmentMode = false)
-        {
-            // line contains given point if there is a scalar s
-            // for which p = From + s * V
-
-            var s = 0.0;
-
-            // to find out the scalar we need to test the first non null component
-            if (!(V.X.EqualsTol(tol, 0))) s = (p.X - From.X) / V.X;
-            else if (!(V.Y.EqualsTol(tol, 0))) s = (p.Y - From.Y) / V.Y;
-            else if (!(V.Z.EqualsTol(tol, 0))) s = (p.Z - From.Z) / V.Z;
-
-            if (segmentMode)
-            {
-                // s is the scalar of V vector that runs From->To
-                if (!(s >= 0.0 && s <= 1.0)) return false;
-            }
-
-            return p.EqualsTol(tol, From.X + s * V.X, From.Y + s * V.Y, From.Z + s * V.Z);
-        }
-
-        /// <summary>
-        /// Finite segment contains point.
-        /// Note: tol must be Constant.NormalizedLengthTolerance
-        /// if comparing normalized vectors
-        /// </summary>
-        public bool SegmentContainsPoint(double tol, Vector3D p)
-        {
-            return LineContainsPoint(tol, p, segmentMode: true);
-        }
-
-        /// <summary>
-        /// Finite segment contains point.
-        /// Note: tol must be Constant.NormalizedLengthTolerance
-        /// if comparing normalized vectors
-        /// </summary>
-        public bool SegmentContainsPoint(double tol, double x, double y, double z)
-        {
-            return LineContainsPoint(tol, x, y, z, segmentMode: true);
-        }
-
-        /// <summary>
-        /// Find intersection of two 3d lines
-        /// </summary>
-        public Vector3D Intersect(double tol, Line3D other)
-        {
-            var f1x = From.X;
-            var f1y = From.Y;
-            var f1z = From.Z;
-
-            var v1x = V.X;
-            var v1y = V.Y;
-            var v1z = V.Z;
-
-            var f2x = other.From.X;
-            var f2y = other.From.Y;
-            var f2z = other.From.Z;
-
-            var v2x = other.V.X;
-            var v2y = other.V.Y;
-            var v2z = other.V.Z;
-
-            // this line  : F + alpha * V
-            // other line : other.F + beta * V
-            //
-            // i = { F + alpha * V == other.F + beta * V }
-            //   = { F1 + alpha * V1 == F2 + beta * V2 }
-            //
-            // i =
-            //   f1x + alpha * v1x == f2x + beta * v2x &&
-            //   f1y + alpha * v1y == f2y + beta * v2y &&
-            //   f1z + alpha * v1z == f2z + beta * v2z
-
-            // XY
-            //   f1x + alpha * v1x == f2x + beta * v2x &&
-            //   f1y + alpha * v1y == f2y + beta * v2y
-            {
-                var alpha_denom = (v1y * v2x - v1x * v2y);
-                var beta_denom = (v1y * v2x - v1x * v2y);
-
-                if (!alpha_denom.EqualsTol(tol, 0) && !beta_denom.EqualsTol(tol, 0))
-                {
-                    var alpha = -(f1y * v2x - f2y * v2x - f1x * v2y + f2x * v2y) / alpha_denom;
-                    var beta = -(f1y * v1x - f2y * v1x - f1x * v1y + f2x * v1y) / beta_denom;
-
-                    var i = From + alpha * V;
-
-                    if (i.EqualsTol(tol, other.From + beta * other.V)) return i;
-                }
-            }
-
-            // XZ
-            //   f1x + alpha * v1x == f2x + beta * v2x &&
-            //   f1z + alpha * v1z == f2z + beta * v2z
-            {
-                var alpha_denom = (v1z * v2x - v1x * v2z);
-                var beta_denom = (v1z * v2x - v1x * v2z);
-
-                if (!alpha_denom.EqualsTol(tol, 0) && !beta_denom.EqualsTol(tol, 0))
-                {
-                    var alpha = -(f1z * v2x - f2z * v2x - f1x * v2z + f2x * v2z) / alpha_denom;
-                    var beta = -(f1z * v1x - f2z * v1x - f1x * v1z + f2x * v1z) / beta_denom;
-
-                    var i = From + alpha * V;
-
-                    if (i.EqualsTol(tol, other.From + beta * other.V)) return i;
-                }
-            }
-
-            // YZ
-            //   f1y + alpha * v1y == f2y + beta * v2y &&
-            //   f1z + alpha * v1z == f2z + beta * v2z
-            {
-                var alpha_denom = (v1z * v2y - v1y * v2z);
-                var beta_denom = (v1z * v2y - v1y * v2z);
-
-                if (!alpha_denom.EqualsTol(tol, 0) && !beta_denom.EqualsTol(tol, 0))
-                {
-                    var alpha = -(f1z * v2y - f2z * v2y - f1y * v2z + f2y * v2z) / alpha_denom;
-                    var beta = -(f1z * v1y - f2z * v1y - f1y * v1z + f2y * v1z) / beta_denom;
-
-                    var i = From + alpha * V;
-
-                    if (i.EqualsTol(tol, other.From + beta * other.V)) return i;
-                }
-            }
-
-            // no intersection
-
-            return null;
-        }
-
-        public Line3D Perpendicular(double tol, Vector3D p)
-        {
-            if (LineContainsPoint(tol, p)) return null;
-
-            return new Line3D(p, p.Project(V));
-        }
-
-        public bool Colinear(double tol, Line3D other)
-        {
-            return LineContainsPoint(tol, other.From) && LineContainsPoint(tol, other.To);
-        }
-
-        public bool IsParallelTo(double tol, Plane3D plane)
-        {
-            return V.IsParallelTo(tol, plane.CS.BaseX) && V.IsParallelTo(tol, plane.CS.BaseY);
-        }
-
-        /// <summary>
-        /// returns null if this line is parallel to the plane,
-        /// the intersection point otherwise
-        /// </summary>
-        public Vector3D Intersect(double tol, Plane3D plane)
-        {
-            if (IsParallelTo(tol, plane)) return null;
-
-            // O = plane.Origin    Vx = plane.CS.BaseX    Vy = plane.CS.BaseY
-            //
-            // plane : O + alpha * Vx + beta * Vy
-            // line  : From + gamma * V
-            //
-            // => m:{ alpha * Vx + beta * Vy - gamma * V } * s = n:{ From - O }
-
-            var m = Matrix3D.FromVectorsAsColumns(plane.CS.BaseX, plane.CS.BaseY, -V);
-            var n = From - plane.CS.Origin;
-            var s = m.Solve(n);
-
-            return From + s.Z * V;
-        }
-        public Vector3D MidPoint { get { return (From + To) / 2; } }
-
-        public override string ToString()
-        {
-            return $"{From}-{To}";
-        }
-
     }

 }


Modified calculation of establishment probability

--- src/PlugIn.cs
+++ src/PlugIn.cs
@@ -235,6 +235,40 @@
             return finalShade;
         }
         //---------------------------------------------------------------------
+
+
+        /// <summary>
+        /// Compute site shade above the grass species
+        /// </summary>
+        // Chihiro 2020.01.22
+        //
+        // Description:
+        //     We just copied ComputeShade method and replaced SiteVars.LAI[site] to SiteVars.LAITree[site]
+        //     to ignore grass species.
+        //
+        public static byte ComputeShadeTree(ActiveSite site)
+        {
+            IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site];
+            byte finalShade = 0;
+            if (!ecoregion.Active)
+                return 0;
+            for (byte shade = 5; shade >= 1; shade--)
+            {
+                if (PlugIn.ShadeLAI[shade] <= 0)
+                {
+                    string mesg = string.Format("Maximum LAI has not been defined for shade class {0}", shade);
+                    throw new System.ApplicationException(mesg);
+                }
+                if (SiteVars.LAITree[site] >= PlugIn.ShadeLAI[shade])
+                {
+                    finalShade = shade;
+                    break;
+                }
+            }
+            return finalShade;
+        }
+        //---------------------------------------------------------------------
+

         protected override void InitializeSite(ActiveSite site)
         {
@@ -400,14 +434,73 @@
         /// germinate/resprout.
         /// This is a Delegate method to base succession.
         /// </summary>
+        ///
+        // W.Hotta and Chihiro modified
+        //
+        // Description:
+        //     - Modify light probability based on the amount of nursery log on the site
+        //
+        //
+        // Psudo-code:
+        //
+        //     double siteShade = site shade calculated by original NECN // This siteShade includes both tree and grass species
+        //     double siteShadeTree = ComputeShadeTree(site)             // Only tree species, excluding grass species
+        //     bool isSufficientlight = false
+        //
+        //     double lightProbability = light probability of original NECN // This lightProbability includes both tree and grass species
+        //     double lightProbabilityTree = light probability ignoring grass layer
+        //     bool found = false
+        //
+        //     int bestShadeClass = 0      // the best shade class for the species which is used for
+        //     string regenType = 'failed' // Identify where the cohort established
+        //                                 // 'failed', 'nlog', or 'surface'
+        //
+        //     // Compute the light probabilities on the site
+        //     foreach lights in sufficientLight:
+        //         identify lightProbability, lightProbabilityTree, and bestShadeClass for the species on the site
+        //
+        //     // Compute the availability of nursery log on the site (nurseryLogAvailability)
+        //     double nurseryLogAvailabilityModifier = 1.0;                    // user defined tuning parameter
+        //     double nurseryLogAvailability = nurseryLogAvailabilityModifier
+        //                                     * ComputeNurseryLogAreaRatio(species, site);
+        //
+        //     // Determine if the species can establish or not
+        //     if The species is CWD-dependent: (Case 1)
+        //         if there is sufficient light above grass layer & enough nursery logs:
+        //             // establish on the nursery log
+        //             isSufficientlight = true
+        //             regenType = 'nlog'
+        //
+        //     else The species can establish on both forest floors & nursery logs (CWD independent): (Case 2)
+        //         if there is sufficient light on forest floor considering both Tree and Grass species LAI:
+        //             // establish on the surface soil
+        //             isSufficientlight = true
+        //             regenType = 'surface'
+        //
+        //         else If (1) the site shade is darker than the best shade class for the species and
+        //                 (2) the light availability above grass species layer meets the species requirement:
+        //             if Threre are sufficient amounts of downed logs:
+        //                 // establish on the nursery log
+        //                 isSufficientlight = true
+        //                 regenType = 'nlog'
+        //
+        //     return isSufficientlight;
+        //
+        //
         public bool SufficientLight(ISpecies species, ActiveSite site)
         {

             //PlugIn.ModelCore.UI.WriteLine("  Calculating Sufficient Light from Succession.");
             byte siteShade = PlugIn.ModelCore.GetSiteVar<byte>("Shade")[site];
+            byte siteShadeTree = ComputeShadeTree(site); // Shade by tree species excluding grass species; Chihiro
+            bool isSufficientlight = false;

             double lightProbability = 0.0;
+            double lightProbabilityTree = 0.0; // Light probability considering LAI of tree species only; Chihiro
             bool found = false;
+
+            int bestShadeClass = 0; // the best shade class for the species; Chihiro
+            string regenType = "failed"; // Identify where the cohort established; Chihiro

             foreach (ISufficientLight lights in sufficientLight)
             {
@@ -421,6 +514,20 @@
                     if (siteShade == 3) lightProbability = lights.ProbabilityLight3;
                     if (siteShade == 4) lightProbability = lights.ProbabilityLight4;
                     if (siteShade == 5) lightProbability = lights.ProbabilityLight5;
+
+                    // Light probability considering LAI of only tree species; Chihiro
+                    if (siteShadeTree == 0) lightProbabilityTree = lights.ProbabilityLight0;
+                    if (siteShadeTree == 1) lightProbabilityTree = lights.ProbabilityLight1;
+                    if (siteShadeTree == 2) lightProbabilityTree = lights.ProbabilityLight2;
+                    if (siteShadeTree == 3) lightProbabilityTree = lights.ProbabilityLight3;
+                    if (siteShadeTree == 4) lightProbabilityTree = lights.ProbabilityLight4;
+                    if (siteShadeTree == 5) lightProbabilityTree = lights.ProbabilityLight5;
+
+                    // Identify the best shade class for the species; Chihiro
+                    bestShadeClass = ComputeBestShadeClass(lights);
+                    // if (PlugIn.ModelCore.CurrentTime == 1)
+                    //     PlugIn.ModelCore.UI.WriteLine("MaxLight:{0},{1}",species.Name, bestShadeClass);
+
                     found = true;
                 }
             }
@@ -428,7 +535,113 @@
             if (!found)
                 PlugIn.ModelCore.UI.WriteLine("A Sufficient Light value was not found for {0}.", species.Name);

-            return modelCore.GenerateUniform() < lightProbability;
+
+            // ------------------------------------------------------------------------
+            // Modify light probability based on the amount of nursery log on the site
+            // W.Hotta 2020.01.22
+            //
+            // Compute the availability of nursery log on the site
+            double nurseryLogAvailabilityModifier = 1.0; // tuning parameter
+            double nurseryLogAvailability = nurseryLogAvailabilityModifier * ComputeNurseryLogAreaRatio(species, site);
+            if (OtherData.CalibrateMode)
+            {
+                PlugIn.ModelCore.UI.WriteLine("original_lightProbability:{0},{1},{2}", PlugIn.ModelCore.CurrentTime, species.Name, lightProbability);
+                PlugIn.ModelCore.UI.WriteLine("siteShade:{0},{1}", siteShade, siteShadeTree);
+                PlugIn.ModelCore.UI.WriteLine("siteLAI:{0}", SiteVars.LAI[site]);
+            }
+
+            // Case 1. CWD-dependent species (species which can only be established on nursery log)
+            if (species.Name == "Picejezo" || species.Name == "Picegleh") // TODO: this should be a functional type parameter
+            {
+                lightProbabilityTree *= nurseryLogAvailability;
+                isSufficientlight = modelCore.GenerateUniform() < lightProbabilityTree;
+                if (isSufficientlight) regenType = "nlog";
+            }
+            // Case 2. CWD-independent species (species which can be established on both forest floor & nursery log)
+            else
+            {
+                // 1. Can the cohort establish on forest floor? (lightProbability is considering both Tree and Grass species)
+                if (modelCore.GenerateUniform() < lightProbability)
+                {
+                    isSufficientlight = true;
+                    regenType = "surface";
+                }
+                else
+                {
+                    // 2. If (1) the site shade is darker than the best shade class for the species and
+                    //       (2) the light availability above grass species layer meets the species requirement,
+                    if (siteShade > bestShadeClass && modelCore.GenerateUniform() < lightProbabilityTree)
+                    {
+                        // 3. check if threre are sufficient amounts of downed logs?
+                        isSufficientlight = modelCore.GenerateUniform() < nurseryLogAvailability;
+                        if (isSufficientlight) regenType = "nlog";
+                    }
+                }
+            }
+
+            if (OtherData.CalibrateMode)
+            {
+                PlugIn.ModelCore.UI.WriteLine("nurseryLogPenalty:{0},{1},{2}", PlugIn.ModelCore.CurrentTime, species.Name, nurseryLogAvailability);
+                PlugIn.ModelCore.UI.WriteLine("modified_lightProbability:{0},{1},{2}", PlugIn.ModelCore.CurrentTime, species.Name, lightProbability);
+                PlugIn.ModelCore.UI.WriteLine("regeneration_type:{0},{1},{2}", PlugIn.ModelCore.CurrentTime, species.Name, regenType);
+            }
+            // ---------------------------------------------------------------------
+
+            return isSufficientlight;
+            //return modelCore.GenerateUniform() < lightProbability;
+        }
+        // Original SufficientLight method
+        //public bool SufficientLight(ISpecies species, ActiveSite site)
+        //{
+
+        //    //PlugIn.ModelCore.UI.WriteLine("  Calculating Sufficient Light from Succession.");
+        //    byte siteShade = PlugIn.ModelCore.GetSiteVar<byte>("Shade")[site];
+
+        //    double lightProbability = 0.0;
+        //    bool found = false;
+
+        //    foreach (ISufficientLight lights in sufficientLight)
+        //    {
+
+        //        //PlugIn.ModelCore.UI.WriteLine("Sufficient Light:  ShadeClass={0}, Prob0={1}.", lights.ShadeClass, lights.ProbabilityLight0);
+        //        if (lights.ShadeClass == species.ShadeTolerance)
+        //        {
+        //            if (siteShade == 0) lightProbability = lights.ProbabilityLight0;
+        //            if (siteShade == 1) lightProbability = lights.ProbabilityLight1;
+        //            if (siteShade == 2) lightProbability = lights.ProbabilityLight2;
+        //            if (siteShade == 3) lightProbability = lights.ProbabilityLight3;
+        //            if (siteShade == 4) lightProbability = lights.ProbabilityLight4;
+        //            if (siteShade == 5) lightProbability = lights.ProbabilityLight5;
+        //            found = true;
+        //        }
+        //    }
+
+        //    if (!found)
+        //        PlugIn.ModelCore.UI.WriteLine("A Sufficient Light value was not found for {0}.", species.Name);
+
+        //    return modelCore.GenerateUniform() < lightProbability;
+
+        //}
+
+
+        //---------------------------------------------------------------------
+        /// <summary>
+        /// Compute the most suitable shade class for the species
+        /// This function identifies the peak of the light establishment table.
+        /// </summary>
+        // Chihiro 2020.01.22
+        //
+        private static int ComputeBestShadeClass(ISufficientLight lights)
+        {
+            int bestShadeClass = 0;
+            double maxProbabilityLight = 0.0;
+            if (lights.ProbabilityLight0 > maxProbabilityLight) bestShadeClass = 0;
+            if (lights.ProbabilityLight1 > maxProbabilityLight) bestShadeClass = 1;
+            if (lights.ProbabilityLight2 > maxProbabilityLight) bestShadeClass = 2;
+            if (lights.ProbabilityLight3 > maxProbabilityLight) bestShadeClass = 3;
+            if (lights.ProbabilityLight4 > maxProbabilityLight) bestShadeClass = 4;
+            if (lights.ProbabilityLight5 > maxProbabilityLight) bestShadeClass = 5;
+            return bestShadeClass;

         }


Fix getting detailed error messages

Fix getting detailed error messages

--- src/SQLite.cs
+++ src/SQLite.cs
@@ -2813,7 +2813,7 @@
 				}
 			}

-			throw SQLiteException.New (r, r.ToString ());
+			throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle));
 		}

 		public IEnumerable<T> ExecuteDeferredQuery<T> ()
@@ -3219,7 +3219,7 @@
 			}
 			else {
 				SQLite3.Reset (Statement);
-				throw SQLiteException.New (r, r.ToString ());
+				throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle));
 			}
 		}


 Changes to be committed:
	modified:   AlmostPDP11/VM/Executor/CommandHandler.cs

added memory mode 1

--- AlmostPDP11/VM/Executor/CommandHandler.cs
+++ AlmostPDP11/VM/Executor/CommandHandler.cs
@@ -34,8 +34,29 @@
                     sourceaddr = "PC";
                 }

-                ushort dest = _memoryManager.GetRegister(destaddr);
-                ushort src = _memoryManager.GetRegister(sourceaddr);
+                ushort dest, destReg = _memoryManager.GetRegister(destaddr);
+                ushort src, srcReg = _memoryManager.GetRegister(sourceaddr);
+
+                switch (command.Operands[Decoder.Decoder.DEST_MODE])
+                {
+                    case 0:
+                        dest = destReg;
+                        break;
+                    case 1:
+                        byte[] word;
+                        word = _memoryManager.GetMemory(destReg, 2);
+                        dest = (ushort)(word[0] << 8);
+                        dest += word[1];
+                        break;
+                    default:
+                        dest = destReg;
+                        break;
+
+
+                }
+
+                //if (command.Operands[Decoder.Decoder.SOURCE_MODE] == 0)
+                    src = srcReg;

                 switch (command.Mnemonic) {
                     case Mnemonic.MOV:
@@ -94,9 +115,21 @@
                         break;
                     case Mnemonic.BIS:
                         dest = (ushort)(dest | src);
+                        _memoryManager.SetStatusFlag("N", false);
+                        if (dest == 0)
+                            _memoryManager.SetStatusFlag("Z", true);
+                        else
+                            _memoryManager.SetStatusFlag("Z", false);
+                        _memoryManager.SetStatusFlag("V", false);
                         break;
                     case Mnemonic.BISB:
                         dest = (ushort)(dest | src);
+                        _memoryManager.SetStatusFlag("N", false);
+                        if (dest == 0)
+                            _memoryManager.SetStatusFlag("Z", true);
+                        else
+                            _memoryManager.SetStatusFlag("Z", false);
+                        _memoryManager.SetStatusFlag("V", false);
                         break;
                     case Mnemonic.ADD:
                         if ((ushort)(dest + src) < dest + src)
@@ -116,7 +149,23 @@
                         break;
                 }

-                _memoryManager.SetRegister(destaddr, dest);
+                switch (command.Operands[Decoder.Decoder.DEST_MODE])
+                {
+                    case 0:
+                        _memoryManager.SetRegister(destaddr, dest);
+                        break;
+                    case 1:
+                        byte[] word = new byte[2];
+                        word[0] = (byte)(dest >> 8);
+                        word[1] = (byte) ((dest << 8) >> 8);
+                        _memoryManager.SetMemory(destReg, word);
+                        break;
+                    default:
+                        _memoryManager.SetRegister(destaddr, dest);
+                        break;
+
+
+                }
             } /*else
                 if (sourcemode < 0 && sourceaddr > 0) {
                     int dest, src = getReg(sourceaddr, sourcemode);


remove duplicate sync method from previous merge

--- src/Wizard.cs
+++ src/Wizard.cs
@@ -30,7 +30,7 @@
             BaseModelSync();
         }

-
+
         //PRIVATE FIELDS
         private string _controllerName { get; }
         private string _areaName { get; }
@@ -52,19 +52,19 @@
         }

         //OVERRIDABLE MEMBERS
+        protected virtual int MaxTabs { get; } = 5;
         protected abstract Steps Steps { get; }
         protected abstract Map Map { get; }
-        protected virtual int MaxTabs { get; } = 5;

         //PUBLIC MEMBERS
         public bool IsStepAvailable(string stepActionName) => _steps.steps.Any(x => x.ActionName == stepActionName);
         public Route CurrentRoute => _map.CurrentRoute;
         public Steps CurrentRouteSteps => new Steps(_currentRouteSteps);
-        public Step CurrentStep => _steps.Current;
+        public Step CurrentStep => _steps.Current;
         public T Model { get; set; } = new T();

         //PUBLIC COMMANDS
-        public void Sync([CallerMemberName] string callerMemberName="")
+        public void Sync([CallerMemberName] string callerMemberName = "")
         {
             if (!TryMoonWalkMove(callerMemberName))
             {
@@ -88,13 +88,6 @@
                 var m = model.GetType().GetProperty(i).GetValue(model, null);
                 typeof(T).GetProperty(i).SetValue(Model, m);
             }
-        }
-        public void Sync() => Sync(new StackTrace().GetFrame(1).GetMethod().Name);
-        public void CommitAndSync(T model)
-        {
-            var callerMethodName = new StackTrace().GetFrame(1).GetMethod().Name;
-            Commit(callerMethodName, model);
-            Sync(callerMethodName);
         }
         public void ClearUnusedSteps()
         {
@@ -135,9 +128,8 @@
         {
             AssertIfCallerMemberNameIsValid(callerMemberName);
             var isMoonWalkNeeded = IsMoonWalkNeeded(callerMemberName);
-            if (!isMoonWalkNeeded)
-            {
-
+            if (!isMoonWalkNeeded)
+            {
                 foreach (var i in CurrentStep.PropertiesToBind ?? Enumerable.Empty<string>())
                 {
                     var m = model.GetType().GetProperty(i).GetValue(model, null);
@@ -146,8 +138,6 @@
             }
             return isMoonWalkNeeded;
         }
-
-
         public bool TryCommitAndSync(T model, [CallerMemberName] string callerMemberName = "")
         {
             AssertIfCallerMemberNameIsValid(callerMemberName);
@@ -169,8 +159,8 @@
             }
             Sync(callerMemberName);
             return isMoonWalkNeeded;
-        }
-        public bool TryMoonWalking([CallerMemberName] string callerMemberName = "") => TryMoonWalkMove(callerMemberName,true);
+        }
+        public bool TryMoonWalking([CallerMemberName] string callerMemberName = "") => TryMoonWalkMove(callerMemberName, true);
         public void MoveNext([CallerMemberName] string callerMemberName = "") => MoveNext(callerMemberName, true);

         //PRIVATE MEMBERS & COMMANDS
@@ -222,7 +212,6 @@
                 BaseModelSync();
             }
         }
-
         private void BaseModelSync()
         {
             this.Model.NavBar = GetNavBar();
@@ -257,7 +246,7 @@
                 }
             }
             return isMoonWalkNeeded;
-        }
+        }
         private bool IsMoonWalkNeeded(string callerMemberName) => (callerMemberName != CurrentStep.ActionName);
         private bool TryMoveNextStep() => TryIterateStep(true);
         private bool TryMovePreviousStep() => TryIterateStep(false);
@@ -273,7 +262,6 @@
             return true;
         }
         private bool IsTriggerPointStep => CurrentStep.TriggerPointRule != null;
-
         private int GetNavBarStatingPointIndex()
         {
             var currentStep = CurrentRoute.RouteSteps.FirstOrDefault(x => x.ActionName == CurrentStep.ActionName);


[appkit] NSRunningApplication.CurrentApplication flag as ThreadSafe

--- src/appkit.cs
+++ src/appkit.cs
@@ -15008,7 +15008,7 @@
 		[Export ("runningApplicationWithProcessIdentifier:")]
 		NSRunningApplication GetRunningApplication (int pid);

-		[Static]
+		[Static][ThreadSafe]
 		[Export ("currentApplication")]
 		NSRunningApplication CurrentApplication { get ; }


IsObservableBeforeCriteria

IsObservableBeforeCriteria

--- Gu.Reactive.Analyzers/ConstructorAnalyzer.cs
+++ Gu.Reactive.Analyzers/ConstructorAnalyzer.cs
@@ -46,8 +46,7 @@
                         context.ReportDiagnostic(Diagnostic.Create(GUREA02ObservableAndCriteriaMustMatch.Descriptor, initializer.GetLocation(), observedText, criteriaText, missingText));
                     }

-                    if (baseCtor.Parameters[0].Type == KnownSymbol.FuncOfT &&
-                        baseCtor.Parameters[1].Type == KnownSymbol.IObservableOfT)
+                    if (IsObservableBeforeCriteria(baseCtor))
                     {
                         context.ReportDiagnostic(Diagnostic.Create(GUREA09ObservableBeforeCriteria.Descriptor, initializer.ArgumentList.GetLocation()));
                     }
@@ -85,8 +84,7 @@
                         context.ReportDiagnostic(Diagnostic.Create(GUREA02ObservableAndCriteriaMustMatch.Descriptor, objectCreation.GetLocation(), observedText, criteriaText, missingText));
                     }

-                    if (ctor.Parameters[0].Type == KnownSymbol.FuncOfT &&
-                        ctor.Parameters[1].Type == KnownSymbol.IObservableOfT)
+                    if (IsObservableBeforeCriteria(ctor))
                     {
                         context.ReportDiagnostic(Diagnostic.Create(GUREA09ObservableBeforeCriteria.Descriptor, objectCreation.ArgumentList.GetLocation()));
                     }
@@ -97,6 +95,14 @@
                     context.ReportDiagnostic(Diagnostic.Create(GUREA06DontNewCondition.Descriptor, objectCreation.GetLocation()));
                 }
             }
+        }
+
+        private static bool IsObservableBeforeCriteria(IMethodSymbol ctor)
+        {
+            return ctor.Parameters.TryElementAt(0, out var parameter0) &&
+                   parameter0.Type == KnownSymbol.FuncOfT &&
+                   ctor.Parameters.TryElementAt(1, out var parameter1) &&
+                   parameter1.Type == KnownSymbol.IObservableOfT;
         }

         private static bool CanBeInlined(ArgumentSyntax argument, SyntaxNodeAnalysisContext context, out InvocationExpressionSyntax result)


Added description for RebusSagaLockingExtension

--- HermaFx.Rebus/Sagas/SagaLockingExtensions.cs
+++ HermaFx.Rebus/Sagas/SagaLockingExtensions.cs
@@ -11,6 +11,13 @@
 {
 	public static class SagaLockingExtensions
 	{
+		/// <summary>
+		/// Extension to allow saga locking while handling messages.
+		/// </summary>
+		/// <param name="configurer">The own RebusSagaConfigurer instance</param>
+		/// <param name="provider">ISagaLockingProvider instance implementation</param>
+		/// <param name="timeout">Nullable Timespan to allow lock retry until TimeOut reached</param>
+		/// <returns>The own RebusSagaConfigurer Instance</returns>
 		public static RebusSagasConfigurer WithSagaLocking(this RebusSagasConfigurer configurer, ISagaLockingProvider provider
 			, TimeSpan? timeout = null)
 		{


Removed now redundant reference from SamplePlugin

--- Oxide.Ext.Rust/Plugins/SamplePlugin.cs
+++ Oxide.Ext.Rust/Plugins/SamplePlugin.cs
@@ -1,6 +1,4 @@
-// Reference: Oxide.Ext.Rust
-
-using Oxide.Core.Plugins;
+using Oxide.Core.Plugins;
 using UnityEngine;

 namespace Oxide.Plugins


fixed capture issue

fixed capture issue

--- CheckersGame/Game.cs
+++ CheckersGame/Game.cs
@@ -104,6 +104,7 @@
                 if (StepSupervisor.IsValidStep(logic.state, step))
                 {
                     logic.updateGameSpace(step);
+                    StepSupervisor.RefreshState(logic.state);
                     logic.ChangePlayer();

                     stepWithNextUser();
@@ -147,6 +148,7 @@
         {
             GameSpace state = (GameSpace)logic.getNextState();
             logic.state = state;
+            StepSupervisor.RefreshState(logic.state);
             //logic.addPlayer(new GTPlayer<Element, Position>().playerWithRealUser(1));
             //logic.addPlayer(new GTPlayer<Element, Position>().playerWithAI(null, 0));
             GUI.SetField(StateToBytes(state));


fixed report path issue for TFS plugin

fixed report path issue for TFS plugin

CPE QCIM1J93134 How to configure Microsoft TFS 'Copy Publish Artifact' task, for API Testing results
JIRA ticket: JENKINS-44364
https://issues.jenkins-ci.org/projects/JENKINS/issues/JENKINS-44364
AGM defect number: 35681

--- HpToolsLauncher/TestRunners/ApiTestRunner.cs
+++ HpToolsLauncher/TestRunners/ApiTestRunner.cs
@@ -72,7 +72,7 @@
             ConsoleWriter.ActiveTestRun = runDesc;
             ConsoleWriter.WriteLine(DateTime.Now.ToString(Launcher.DateFormat) + " Running: " + testinf.TestPath);

-            runDesc.ReportLocation = Helper.CreateTempDir();
+            runDesc.ReportLocation = testinf.TestPath;
             runDesc.ErrorDesc = errorReason;
             runDesc.TestPath = testinf.TestPath;
             runDesc.TestState = TestState.Unknown;


[Fixes bug #730825] Allow keyboard shortcuts to be handled if the Text Tool is active but not in edit mode.

--- Pinta.Tools/Tools/TextTool/TextTool.cs
+++ Pinta.Tools/Tools/TextTool/TextTool.cs
@@ -605,6 +605,11 @@
 					RedrawText (true, true);

 			}
+            else
+            {
+                // If we're not editing, allow the key press to be handled elsewhere (e.g. for selecting another tool).
+                keyHandled = false;
+            }

 			args.RetVal = keyHandled;
 		}


assembly version

assembly version

--- PocketSharp/Properties/AssemblyInfo.cs
+++ PocketSharp/Properties/AssemblyInfo.cs
@@ -22,5 +22,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("4.1.5.2")]
-[assembly: AssemblyFileVersion("4.1.5.2")]+[assembly: AssemblyVersion("4.1.5.3")]
+[assembly: AssemblyFileVersion("4.1.5.3")]


Receive puzzle arguments in API

Receive puzzle arguments in API

Refactor the API to support receiving file uploads and arguments for the puzzles as an HTTP form.

--- src/AdventOfCode/Startup.cs
+++ src/AdventOfCode/Startup.cs
@@ -6,8 +6,11 @@
     using System;
     using System.Diagnostics;
     using System.Globalization;
+    using System.IO;
     using System.Linq;
     using System.Reflection;
+    using System.Text;
+    using System.Threading;
     using System.Threading.Tasks;
     using Microsoft.AspNetCore.Builder;
     using Microsoft.AspNetCore.Hosting;
@@ -51,7 +54,7 @@
                 {
                     endpoints.MapGet("/error", ErrorAsync);
                     endpoints.MapGet("/api/puzzles", GetPuzzlesAsync);
-                    endpoints.MapGet("/api/puzzles/{year:int}/{day:int}/solve", SolvePuzzleAsync);
+                    endpoints.MapPost("/api/puzzles/{year:int}/{day:int}/solve", SolvePuzzleAsync);
                 });
         }

@@ -136,11 +139,11 @@
         /// </returns>
         private static async Task SolvePuzzleAsync(HttpContext context)
         {
-            ////if (!context.Request.HasJsonContentType())
-            ////{
-            ////    context.Response.StatusCode = StatusCodes.Status415UnsupportedMediaType;
-            ////    return;
-            ////}
+            if (!context.Request.HasFormContentType)
+            {
+                context.Response.StatusCode = StatusCodes.Status415UnsupportedMediaType;
+                return;
+            }

             int year = int.Parse((string)context.Request.RouteValues["year"] !, CultureInfo.InvariantCulture);
             int day = int.Parse((string)context.Request.RouteValues["day"] !, CultureInfo.InvariantCulture);
@@ -159,20 +162,50 @@
                 return;
             }

-            ////var syncIOFeature = context.Features.Get<IHttpBodyControlFeature>();
-            ////
-            ////if (syncIOFeature != null)
-            ////{
-            ////    syncIOFeature.AllowSynchronousIO = true;
-            ////}
-            ////
-            ////puzzle.Resource = context.Request.Body;
+            var form = await context.Request.ReadFormAsync(context.RequestAborted);
+
+            var metadata = puzzle.Metadata() !;
+
+            if (metadata.RequiresData)
+            {
+                if (!form.TryGetValue("resource", out var resource))
+                {
+                    await WriteErrorAsync(context, StatusCodes.Status400BadRequest, "Bad Request", "No puzzle resource provided.");
+                    return;
+                }
+
+                puzzle.Resource = new MemoryStream(Encoding.UTF8.GetBytes(resource));
+            }
+
+            string[] arguments = Array.Empty<string>();
+
+            if (form.TryGetValue("arguments", out var values))
+            {
+                arguments = values.Select((p) => p).ToArray();
+            }
+
+            if (arguments.Length < metadata.MinimumArguments)
+            {
+                await WriteErrorAsync(context, StatusCodes.Status400BadRequest, "Bad Request", $"The puzzle requires at least {metadata.MinimumArguments} argument(s).");
+                return;
+            }
+
+            var timeout = TimeSpan.FromMinutes(1);
+
+            using var cts = CancellationTokenSource.CreateLinkedTokenSource(context.RequestAborted);
+            cts.CancelAfter(timeout);

             var stopwatch = Stopwatch.StartNew();

             try
             {
-                puzzle.Solve(Array.Empty<string>());
+                // TODO Make async and pass through CancellationToken
+                puzzle.Solve(arguments);
+            }
+            catch (OperationCanceledException)
+            {
+                await WriteErrorAsync(context, StatusCodes.Status408RequestTimeout, "Request Timeout", $"The puzzle was not solved within {timeout}.");
+                return;
             }
             catch (PuzzleException ex)
             {


Fixed a problem with Simian horizontal jump impulse, fixed swimming at improper water level sometimes.

git-svn-id: baf6e02d125cf6f9bfcfe153b2eb83d6e1f5ace6@2169 52acb1d6-8a22-11de-b505-999d5b087335

--- Programs/Simian/Extensions/Movement.cs
+++ Programs/Simian/Extensions/Movement.cs
@@ -17,8 +17,8 @@
         const float FLY_SPEED = 10f; //meters/sec
         const float FALL_DELAY = 0.33f; //seconds before starting animation
         const float FALL_FORGIVENESS = 0.25f; //fall buffer in meters
-        const float JUMP_IMPULSE_VERTICAL = 8f; //boost amount in meters/sec
-        const float JUMP_IMPULSE_HORIZONTAL = 40f; //boost amount in meters/sec
+        const float JUMP_IMPULSE_VERTICAL = 8.5f; //boost amount in meters/sec
+        const float JUMP_IMPULSE_HORIZONTAL = 10f; //boost amount in meters/sec (no clue why this is so high)
         const float PREJUMP_DELAY = 0.25f; //seconds before actually jumping
         const float AVATAR_TERMINAL_VELOCITY = 54f; //~120mph

@@ -184,7 +184,7 @@
                             gravity = 0f;
                             agent.Avatar.Velocity *= 0.5f;
                             agent.Avatar.Velocity.Z = 0f;
-                            if (move.Z < 0) agent.Avatar.Position.Z = waterChestHeight;
+                            if (move.Z < 1) agent.Avatar.Position.Z = waterChestHeight;

                             if (move.Z > 0)
                             {
@@ -240,8 +240,8 @@
                                     animsChanged = true;

                                 agent.Avatar.Velocity.Z = JUMP_IMPULSE_VERTICAL * seconds;
-                                agent.Avatar.Velocity.X += agent.Avatar.Acceleration.X * JUMP_IMPULSE_HORIZONTAL * seconds;
-                                agent.Avatar.Velocity.Y += agent.Avatar.Acceleration.Y * JUMP_IMPULSE_HORIZONTAL * seconds;
+                                agent.Avatar.Velocity.X += agent.Avatar.Acceleration.X * JUMP_IMPULSE_HORIZONTAL;
+                                agent.Avatar.Velocity.Y += agent.Avatar.Acceleration.Y * JUMP_IMPULSE_HORIZONTAL;
                             }
                             else move.Z = 0; //override Z control
                         }


Change ReSharperPluginLatest value from null to latest

--- source/Nuke.Common/Tools/ReSharper/ReSharperTasks.cs
+++ source/Nuke.Common/Tools/ReSharper/ReSharperTasks.cs
@@ -17,7 +17,7 @@
 {
     public partial class ReSharperTasks
     {
-        public const string ReSharperPluginLatest = null;
+        public const string ReSharperPluginLatest = "latest";

         private static void PreProcess<T>(ref T toolSettings) where T : ReSharperSettingsBase
         {
@@ -33,10 +33,12 @@
                 DirectoryExistsPolicy.Merge,
                 FileExistsPolicy.OverwriteIfNewer);

-            toolSettings.Plugins.ForEach(x => HttpTasks.HttpDownloadFile(
-                $"http://resharper-plugins.jetbrains.com/dotnet/api/v2/curated-feeds/Wave_v{wave}.0/Packages(Id='{x.Key}',Version='{x.Value}')/Download",
-                Path.Combine(shadowDirectory, $"{x.Key}.nupkg")));
-
+            toolSettings.Plugins
+                .Select(x => (Plugin: x.Key, Version: x.Value == ReSharperPluginLatest ? null : x.Value))
+                .ForEach(x => HttpTasks.HttpDownloadFile(
+                    $"http://resharper-plugins.jetbrains.com/dotnet/api/v2/curated-feeds/Wave_v{wave}.0/Packages(Id='{x.Plugin}',Version='{x.Version}')/Download",
+                    Path.Combine(shadowDirectory, $"{x.Plugin}.nupkg")));
+
             toolSettings = toolSettings.SetProcessToolPath(Path.Combine(shadowDirectory, Path.GetFileName(toolSettings.ProcessToolPath)));
         }


Issue #30252 is by design (#31656)

Issue #30252 is by design (#31656)

--- src/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs
+++ src/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs
@@ -30,7 +30,7 @@
         }

         [Fact]
-        [ActiveIssue(30252, ~TargetFrameworkMonikers.NetFramework)]
+        [SkipOnTargetFramework(~TargetFrameworkMonikers.NetFramework, "Assembly.Load ignores CodeBase by design, except on netfx. See https://github.com/dotnet/coreclr/issues/10561")]
         public void CompiledAssembly_ValidPathToAssembly_ReturnsExpected()
         {
             var results = new CompilerResults(null) { PathToAssembly = typeof(int).Assembly.EscapedCodeBase };


Add NetBSD support for the sysconf(_SC_NPROCESSORS_ONLN) call

/usr/include/sys/unistd.h:#define       _SC_NPROCESSORS_ONLN    1002

--- src/System.Runtime.Extensions/tests/System/Environment.ProcessorCount.cs
+++ src/System.Runtime.Extensions/tests/System/Environment.ProcessorCount.cs
@@ -31,7 +31,10 @@
         public void Unix_ProcessorCountTest()
         {
             //arrange
-            int _SC_NPROCESSORS_ONLN = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? 84 : 58;
+            int _SC_NPROCESSORS_ONLN =
+                RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? 84 :
+                RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")) ? 1002 :
+                58;
             int expected = (int)sysconf(_SC_NPROCESSORS_ONLN);

             //act