Added in-memory request queue to enable clean shutdown without losing events.

Requests will now be given a chance to complete before quitting when
ControlledShutdown is enabled.

The following parameters control the behavior:

/// <summary>
/// Whether or not to prevent Application.Quit and fire off
/// the OnShutdown method & event. This only works in builds.
/// </summary>
public bool ControlledShutdown = true;

/// <summary>
/// If ControlledShutdown is enabled, the application will
/// automatically quit after this period of time has elapsed.
/// </summary>
public float ControlledShutdownTimeout = 5.0f;

/// <summary>
/// How long to suspend the main thread (in seconds) in OnDestroy
/// to give any outstanding network calls time to complete. This
/// only occcurs while running in the editor.
/// </summary>
public float InEditorSleepDuration = 5.0f;

--- KeenPlugin/Assets/Helios/Keen/Client.cs
+++ KeenPlugin/Assets/Helios/Keen/Client.cs
@@ -47,6 +47,25 @@
             /// Optional cache provider
             /// </summary>
             public ICacheProvider CacheInstance;
+
+            /// <summary>
+            /// Whether or not to prevent Application.Quit and fire off
+            /// the OnShutdown method & event. This only works in builds.
+            /// </summary>
+            public bool ControlledShutdown = true;
+
+            /// <summary>
+            /// If ControlledShutdown is enabled, the application will
+            /// automatically quit after this period of time has elapsed.
+            /// </summary>
+            public float ControlledShutdownTimeout = 5.0f;
+
+            /// <summary>
+            /// How long to suspend the main thread (in seconds) in OnDestroy
+            /// to give any outstanding network calls time to complete. This
+            /// only occcurs while running in the editor.
+            /// </summary>
+            public float InEditorSleepDuration = 5.0f;
         }

         /// <summary>
@@ -78,6 +97,56 @@
         private bool                        m_Caching   = false;
         private Config                      m_Settings  = null;
         private List<ICacheProvider.Entry>  m_Cached    = new List<ICacheProvider.Entry>();
+
+        class Request
+        {
+            public WWW RequestData;
+            public string EventName;
+            public string EventData;
+            public Action<CallbackData> Callback;
+            public EventStatus Status;
+
+            public bool IsDone
+            {
+                get
+                {
+                    return RequestData != null && RequestData.isDone;
+                }
+            }
+
+            public void Dispose()
+            {
+                if (RequestData != null)
+                    RequestData.Dispose();
+            }
+        }
+
+        /// <summary>
+        /// A list of outstanding requests. An in-memory queue of requests.
+        /// </summary>
+        private List<Request> _requestQueue = new List<Request>();
+
+        /// <summary>
+        /// Whether the application is currently qutting.
+        /// </summary>
+        private bool m_Quitting = false;
+
+        /// <summary>
+        /// Whether to allow the application to quit (if Settings.ControlledShutdown is enabled).
+        /// </summary>
+        private bool m_AllowQuitting = true;
+
+        private event Action _shutdown;
+
+        /// <summary>
+        /// An event that gets fired when the application is quitting that enables last-minute
+        /// events to be sent cleanly. Only fired if Settings.ControlledShutdown is enabled.
+        /// </summary>
+        public event Action Shutdown
+        {
+            add { _shutdown += value; }
+            remove { _shutdown -= value; }
+        }

         /// <summary>
         /// Instance settings. Use this to provide your Keen project settings.
@@ -101,6 +170,9 @@
                 else if (Settings.CacheSweepInterval <= 0.5f)
                     Debug.LogError("[Keen] cache sweep interval is invalid.");
                 else m_Validated = true;
+
+                // If we are in ControlledShutdown mode, don't allow quitting.
+                m_AllowQuitting = !value.ControlledShutdown;
             }
         }

@@ -240,31 +312,97 @@
                 , Settings.ProjectId, event_name),
                 System.Text.Encoding.ASCII.GetBytes(event_data), headers);

+            Request request = new Request { RequestData = keen_server, EventName = event_name, EventData = event_data, Callback = callback, Status = status };
+
+            QueueRequest(request);
+
             yield return keen_server;

-            if (!String.IsNullOrEmpty(keen_server.error))
-            {
-                Debug.LogErrorFormat("[Keen]: {0}", keen_server.error);
-
-                if (status == EventStatus.None &&
+            DequeRequest(request);
+
+            if (!CheckRequest(request))
+            {
+                CacheRequest(request);
+            }
+        }
+
+        private void QueueRequest(Request request)
+        {
+            _requestQueue.Add(request);
+        }
+
+        private void DequeRequest(Request request)
+        {
+            _requestQueue.Remove(request);
+        }
+
+        /// <summary>
+        /// Checks if the queued request succeeded.
+        /// </summary>
+        /// <param name="request">The queued request</param>
+        /// <returns>True on a successful request; otherwise, false.</returns>
+        private bool CheckRequest(Request request)
+        {
+            if (!String.IsNullOrEmpty(request.RequestData.error))
+            {
+                Debug.LogErrorFormat("[Keen]: {0}", request.RequestData.error);
+                return false;
+            }
+
+            Debug.LogFormat("[Keen] sent successfully: {0}", request.EventName);
+                if (request.Callback != null)
+                    request.Callback.Invoke(new CallbackData
+                    { status = EventStatus.Submitted, data = request.EventData, name = request.EventName });
+
+            return true;
+        }
+
+        /// <summary>
+        /// Checks if the queued request failed and if so, caches it.
+        /// </summary>
+        /// <param name="request">A valid queued request</param>
+        private void CacheRequest(Request request)
+        {
+            if (!String.IsNullOrEmpty(request.RequestData.error))
+            {
+                Debug.LogErrorFormat("[Keen]: {0}", request.RequestData.error);
+
+                if (request.Status == EventStatus.None &&
                     Settings.CacheInstance != null &&
                     Settings.CacheInstance.Ready() &&
-                    Settings.CacheInstance.Write(new ICacheProvider.Entry { name = event_name, data = event_data }))
-                {
-                    if (callback != null)
-                        callback.Invoke(new CallbackData
-                        { status = EventStatus.Cached, data = event_data, name = event_name });
-                }
-                else if (callback != null)
-                    callback.Invoke(new CallbackData
-                    { status = EventStatus.Failed, data = event_data, name = event_name });
+                    Settings.CacheInstance.Write(new ICacheProvider.Entry { name = request.EventName, data = request.EventData }))
+                {
+                    if (request.Callback != null)
+                        request.Callback.Invoke(new CallbackData
+                        { status = EventStatus.Cached, data = request.EventData, name = request.EventName });
+                }
+                else if (request.Callback != null)
+                    request.Callback.Invoke(new CallbackData
+                    { status = EventStatus.Failed, data = request.EventData, name = request.EventName });
             }
             else
             {
-                Debug.LogFormat("[Keen] sent successfully: {0}", event_name);
-                if (callback != null)
-                    callback.Invoke(new CallbackData
-                    { status = EventStatus.Submitted, data = event_data, name = event_name });
+                Debug.LogFormat("[Keen] sent successfully: {0}", request.EventName);
+                if (request.Callback != null)
+                    request.Callback.Invoke(new CallbackData
+                    { status = EventStatus.Submitted, data = request.EventData, name = request.EventName });
+            }
+        }
+
+        /// <summary>
+        /// Synchronously iterates over and disposes all queued requests.
+        /// This results in a call to WWW.Dispose any any requests where
+        /// the underlaying WWW object is not done, which will return from
+        /// any yield statements waiting on the WWW request.
+        /// </summary>
+        private void DisposeQueuedRequests()
+        {
+            foreach (Request queuedRequest in _requestQueue)
+            {
+                if (!queuedRequest.IsDone)
+                {
+                    queuedRequest.Dispose();
+                }
             }
         }

@@ -308,10 +446,110 @@
         /// </summary>
         void OnDestroy()
         {
-            StopAllCoroutines();
+            if (Application.isEditor)
+            {
+                OnShutdown();
+
+                if (_requestQueue.Count > 0)
+                {
+                    Debug.LogWarning(@"[Keen] There were outstanding queued requests on shutdown. This
+                                may be caused by an unresponsive or non-existant connection to the
+                                remote server.");
+
+                    if (Settings.InEditorSleepDuration > 0)
+                    {
+                        Debug.LogWarning(@"[Keen] Editor may hang briefly while outstanding queued
+                                        requests are given a chance to complete.");
+
+                        // Allow network calls (initiated via WWW class) to finish up
+                        System.Threading.Thread.Sleep((int)Settings.InEditorSleepDuration * 1000);
+                    }
+
+                    DisposeQueuedRequests();
+                }
+            }
+
+            //StopAllCoroutines();

             if (Settings != null && Settings.CacheInstance != null)
                 Settings.CacheInstance.Dispose();
+        }
+
+        void OnApplicationQuit()
+        {
+            // Debug
+            //Debug.Log("OnApplicationQuit");
+
+            if (!m_AllowQuitting)
+            {
+                if (!Application.isEditor)
+                    Debug.LogWarning("[Keen] Canceling application quit to perform shutdown logic.");
+
+                Application.CancelQuit();
+            }
+
+            if (m_Quitting)
+                return;
+
+            m_Quitting = true;
+
+            if (Settings.ControlledShutdown)
+            {
+                if (!Application.isEditor)
+                {
+                    OnShutdown();
+
+                    InvokeRepeating("QuitOnEmptyRequestQueue", 0.0f, 0.5f);
+
+                    // Creates a timeout for quitting the application cleanly incase the requests in the queue
+                    // don't complete fast enough.
+                    StartCoroutine(QuitOnTimeout());
+                }
+            }
+        }
+
+        private IEnumerator QuitOnTimeout()
+        {
+            Debug.LogFormat("[Keen] Quit timeout started at {0}.", System.DateTime.Now.ToShortTimeString());
+
+            yield return new WaitForSeconds(Settings.ControlledShutdownTimeout);
+
+            // Quit timeout has elapsed. Cancel the QuitOnEmptyRequestQueue repeating invocation.
+            if (IsInvoking("QuitOnEmptyRequestQueue"))
+                CancelInvoke("QuitOnEmptyRequestQueue");
+
+            Debug.LogFormat("[Keen] Quit timeout elapsed at {0}.", System.DateTime.Now.ToShortTimeString());
+
+            DisposeQueuedRequests();
+
+            Debug.LogFormat("Quitting at {0}.", System.DateTime.Now.ToShortTimeString());
+
+            m_AllowQuitting = true;
+            Application.Quit();
+        }
+
+        private void QuitOnEmptyRequestQueue()
+        {
+            if (_requestQueue.Count == 0)
+            {
+                Debug.LogFormat("No queued requests. Quitting...");
+                // No more need for a quit timeout. We are quitting.
+                StopCoroutine(QuitOnTimeout());
+                m_AllowQuitting = true;
+                Application.Quit();
+            }
+        }
+
+        /// <summary>
+        /// A hook that gets called when the application is quitting that enables last-minute
+        /// events to be sent cleanly. Only works if Settings.ControlledShutdown is enabled.
+        /// Can be overridden in derived classes. Must call base.OnShutdown or Shutdown event
+        /// will not be fired.
+        /// </summary>
+        protected virtual void OnShutdown()
+        {
+            if (_shutdown != null)
+                _shutdown();
         }

         /// <summary>


too much creation

too much creation

--- King.Service/Data/Azure/TableStorage.cs
+++ King.Service/Data/Azure/TableStorage.cs
@@ -34,8 +34,6 @@
             }

             this.tableName = tableName;
-
-            this.CreateIfNotExists().RunSynchronously();
         }
         #endregion


Added another comment in KrystalFamily.cs

--- Krystals4ObjectLibrary/KrystalFamily.cs
+++ Krystals4ObjectLibrary/KrystalFamily.cs
@@ -198,7 +198,8 @@

                 if(maxIndex == -1)
                 {
-                    // none of the inputs were found in the _dependency list
+                    // None of this dependency's inputs were found in the _dependencyList
+                    // but it may be the input of a dependency that has not yet been added.
                     _dependencyList.Add(d);
                 }
                 else


Fixed up some variable naming that was changed by some errant clean-up settings.

--- Lml/Importers/AppleITunesXmlImporter.cs
+++ Lml/Importers/AppleITunesXmlImporter.cs
@@ -16,9 +16,9 @@
         {
             Validator.IsNotNull(readerAtStartOfDocument, "readerAtStartOfDocument");

-            XDocument doc = XDocument.Load(readerAtStartOfDocument);
+            var doc = XDocument.Load(readerAtStartOfDocument);

-            XDocumentType documentType = doc.DocumentType;
+            var documentType = doc.DocumentType;
             var requiredDocumentType = new XDocumentType("plist", "-//Apple Computer//DTD PLIST 1.0//EN",
                                                          "http://www.apple.com/DTDs/PropertyList-1.0.dtd", "");
             if (!XNode.DeepEquals(documentType, requiredDocumentType))
@@ -28,14 +28,14 @@
                                                       @"<!DOCTYPE plist PUBLIC ""-//Apple Computer//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd"">");
             }

-            XElement root = doc.Element("plist");
+            var root = doc.Element("plist");
             if (root == null)
             {
                 throw new ArgumentOutOfRangeException("readerAtStartOfDocument",
                                                       "The provided TextReader's document does not contain the required plist root node.");
             }

-            XAttribute version = root.Attribute("version");
+            var version = root.Attribute("version");
             if (version == null || version.Value != LibraryVersion)
             {
                 throw new ArgumentOutOfRangeException("readerAtStartOfDocument",
@@ -49,7 +49,7 @@
         {
             Validator.IsNotNull(plistRootNode, "plistRootNode");

-            XElement mainDict = plistRootNode.Element("dict");
+            var mainDict = plistRootNode.Element("dict");
             if (mainDict == null)
             {
                 throw new ArgumentOutOfRangeException("plistRootNode",
@@ -100,9 +100,9 @@
         {
             Validator.IsNotNull(reader, "reader");

-            XElement plistRootNode = GetPlistRootNode(reader);
-            XElement mainDictNode = GetPlistDictNode(plistRootNode);
-            IDictionary<string, object> metadata = GetPrimitiveEntries(mainDictNode);
+            var plistRootNode = GetPlistRootNode(reader);
+            var mainDictNode = GetPlistDictNode(plistRootNode);
+            var metadata = GetPrimitiveEntries(mainDictNode);

             object version;
             if (!metadata.TryGetValue("Application Version", out version))
@@ -143,7 +143,7 @@

         private static Item GetItem(XElement dict, LibraryMode libraryMode)
         {
-            IDictionary<string, object> entries = GetPrimitiveEntries(dict);
+            var entries = GetPrimitiveEntries(dict);

             object artist;
             entries.TryGetValue("Artist", out artist);


Improve Spotify title detection

Improve Spotify title detection

Spotify continues to lock down its service and removed the playback info from the window title in the latest update. In case this is ever re-added, additional metadata handling for Spotify Premium is added.

--- LocalAudioBroadcast/Metadata/Spotify.cs
+++ LocalAudioBroadcast/Metadata/Spotify.cs
@@ -26,9 +26,9 @@
     /// </summary>
     class Spotify : ITrackInfoProvider {

-        private const string SPOTIFY_TITLE = "Spotify";
+        // Order if the titles is important, most specific (longest) title must come first
+        private static string[] SPOTIFY_TITLES = { "Spotify Premium", "Spotify" };
         private const string SPOTIFY_TITLE_SEPARATOR = " – ";
-        private const string SPOTIFY_PLAYBACK_TITLE_PREFIX = SPOTIFY_TITLE + SPOTIFY_TITLE_SEPARATOR;

         private Process spotifyProcess;
         private volatile bool _threadRunning;
@@ -57,10 +57,20 @@
                 if (UpdateSpotifyProcess()) {
                     string title = spotifyProcess.MainWindowTitle;

+                    string spotifyTitle = "";
+                    string spotifyTitlePrefix = "";
+                    foreach(string st in SPOTIFY_TITLES) {
+                        if (title.StartsWith(st)) {
+                            spotifyTitle = st;
+                            spotifyTitlePrefix = st + SPOTIFY_TITLE_SEPARATOR;
+                            break;
+                        }
+                    }
+
                     // remove Spotify title prefix
-                    if (title.Length > SPOTIFY_PLAYBACK_TITLE_PREFIX.Length)
-                        title = title.Substring(SPOTIFY_PLAYBACK_TITLE_PREFIX.Length);
-                    else if (title.Equals(SPOTIFY_TITLE))
+                    if (title.Length > spotifyTitlePrefix.Length)
+                        title = title.Substring(spotifyTitlePrefix.Length);
+                    else if (title.Equals(spotifyTitle))
                         title = "N/A";

                     return title;


Changed string.Format to StringBuilder

Changed string.Format to StringBuilder

--- src/Microsoft.AspNet.Http.Extensions/UriHelper.cs
+++ src/Microsoft.AspNet.Http.Extensions/UriHelper.cs
@@ -2,6 +2,7 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

 using System;
+using System.Text;

 namespace Microsoft.AspNet.Http.Extensions
 {
@@ -10,6 +11,8 @@
     /// </summary>
     public static class UriHelper
     {
+        private const string SchemeDelimiter = "://";
+
         /// <summary>
         /// Combines the given URI components into a string that is properly encoded for use in HTTP headers.
         /// </summary>
@@ -48,7 +51,15 @@
             FragmentString fragment = new FragmentString())
         {
             string combinePath = (pathBase.HasValue || path.HasValue) ? (pathBase + path).ToString() : "/";
-            return $"{scheme}://{host.ToString()}{combinePath}{query.ToString()}{fragment.ToString()}";
+
+            return new StringBuilder()
+                .Append(scheme)
+                .Append(SchemeDelimiter)
+                .Append(host.ToString())
+                .Append(combinePath)
+                .Append(query.ToString())
+                .Append(fragment.ToString())
+                .ToString();
         }

         /// <summary>
@@ -93,7 +104,14 @@
         /// <returns></returns>
         public static string GetDisplayUrl(this HttpRequest request)
         {
-            return request.Scheme + "://" + request.Host.Value + request.PathBase.Value + request.Path.Value + request.QueryString.Value;
+            return new StringBuilder()
+                .Append(request.Scheme)
+                .Append(SchemeDelimiter)
+                .Append(request.Host.Value)
+                .Append(request.PathBase.Value)
+                .Append(request.Path.Value)
+                .Append(request.QueryString.Value)
+                .ToString();
         }
     }
 }


Update Game.Database.cs

Update Game.Database.cs


right click now deselects everything

right click now deselects everything

--- CircuitCrawlerEditor/FormEditor.cs
+++ CircuitCrawlerEditor/FormEditor.cs
@@ -169,53 +169,56 @@
 		{
 			Vector2 pos = ScreenToWorld(new Vector2(e.Location.X, e.Location.Y), true);

-			foreach (Tile[] t in level.Tileset.Tiles)
-			{
-				foreach (Tile tile in t)
-				{
-					if (PointInSquare(pos, tile.Position, Tile.SIZE))
-					{
-						if (selectedTile == tile)
+			if (e.Button == System.Windows.Forms.MouseButtons.Left)
+			{
+				foreach (Tile[] t in level.Tileset.Tiles)
+				{
+					foreach (Tile tile in t)
+					{
+						if (PointInSquare(pos, tile.Position, Tile.SIZE))
 						{
-							selectedTile = null;
+							if (selectedTile == tile)
+							{
+								selectedTile = null;
+							}
+							else
+							{
+								selectedTile = tile;
+								TreeNodeCollection nodes = levelItemsList.Nodes;
+								foreach (TreeNode node in nodes)
+								{
+									if (node.Tag == selectedTile)
+									{
+										levelItemsList.SelectedNode = node;
+										break;
+									}
+								}
+								selectedItemProperties.SelectedObject = selectedTile;
+							}
 						}
-						else
-						{
-							selectedTile = tile;
-							TreeNodeCollection nodes = levelItemsList.Nodes;
-							foreach (TreeNode node in nodes)
-							{
-								if (node.Tag == selectedTile)
-								{
-									levelItemsList.SelectedNode = node;
-									break;
-								}
-							}
-							selectedItemProperties.SelectedObject = selectedTile;
-						}
-					}
-				}
-			}
-
-			if (selectedTile == null && selectedEntity == null && selectedLight == null)
-			{
-				selectedItemProperties.SelectedObject = null;
-				selectionCube.Hidden = true;
-			}
-			else
-			{
-				selectionCube.Hidden = false;
-				if (selectedTile != null)
-				{
-					selectionCube.Position = selectedTile.Position;
-				}
-				if (selectedEntity != null)
-				{
-					selectionCube.Position = new Vector2(selectedEntity.XPos, selectedEntity.YPos);
-				}
-				if (selectedLight != null)
-				{
-					selectionCube.Position = selectedLight.Position.Xy;
+					}
+				}
+
+				if (selectedTile == null && selectedEntity == null && selectedLight == null)
+				{
+					selectedItemProperties.SelectedObject = null;
+					selectionCube.Hidden = true;
+				}
+				else
+				{
+					selectionCube.Hidden = false;
+					if (selectedTile != null)
+					{
+						selectionCube.Position = selectedTile.Position;
+					}
+					if (selectedEntity != null)
+					{
+						selectionCube.Position = new Vector2(selectedEntity.XPos, selectedEntity.YPos);
+					}
+					if (selectedLight != null)
+					{
+						selectionCube.Position = selectedLight.Position.Xy;
+					}
 				}
 			}
 		}
@@ -300,6 +303,15 @@
 						}
 					}
 				}
+			}
+
+			if (e.Button == MouseButtons.Right)
+			{
+				selectedEntity = null;
+				selectedLight = null;
+				selectedTile = null;
+				selectedItemProperties.SelectedObject = null;
+				selectionCube.Hidden = true;
 			}
 		}


When reading packet make sure to pass the page index, not the page number to the FirstPage prop

--- MLabs.Ogg/src/Container/PacketReader.cs
+++ MLabs.Ogg/src/Container/PacketReader.cs
@@ -50,7 +50,6 @@
                 if (hasPacket && page.PageType != PageType.Continuation)
                         throw new InvalidStreamException("Packet didn't finish on previous page, but next page is not marked as Continuation");

-                pageIndex++;
                 foreach (var segment in page.Segments)
                 {
                     //start new packet
@@ -75,6 +74,7 @@
                     hasPacket = false;
                     numberOfSegments = 0;
                 }
+                pageIndex++;
             }
             yield break;
         }


Fixed file permissions

Fixed file permissions


don't show windows while they're loading

--- TCC.Core/Windows/TccWindow.cs
+++ TCC.Core/Windows/TccWindow.cs
@@ -71,8 +71,9 @@
             _ignoreSize = ignoreSize;
             _undimOnFlyingGuardian = undimOnFlyingGuardian;

-            _opacityAnimation = new DoubleAnimation() { Duration = TimeSpan.FromMilliseconds(100) };
-
+            _opacityAnimation = new DoubleAnimation { Duration = TimeSpan.FromMilliseconds(100) };
+
+            MainContent.Opacity = 0;
             Topmost = true;
             Left = settings.X * Settings.ScreenW;
             Top = settings.Y * Settings.ScreenH;
@@ -88,11 +89,6 @@
             _settings.VisibilityChanged += OnWindowVisibilityChanged;

             Loaded += OnLoaded;
-            Closing += (_, args) =>
-            {
-                //args.Cancel = true;
-                //Hide();
-            };
             SizeChanged += OnSizeChanged;

             WindowManager.ForegroundManager.VisibilityChanged += OnVisibilityChanged;


Update EAXSolverTests.cs

Update EAXSolverTests.cs


Modify slider to adapt multiple load/unload events


Update SecurityCache.cs

Update SecurityCache.cs

--- Common/Securities/SecurityCache.cs
+++ Common/Securities/SecurityCache.cs
@@ -106,13 +106,14 @@
                 return;
             }

+            // Only cache no fill-forward data.
+            if(data.IsFillForward) return;
+
             // Always keep track of the last obesrvation
             _dataByType[data.GetType()] = data;
             if (_lastData != null)
             {
-                // Only cache no fill-forward data.
-                if (data.IsFillForward
-                    || _lastData.DataType == MarketDataType.QuoteBar
+                if (_lastData.DataType == MarketDataType.QuoteBar
                     && data.DataType == MarketDataType.TradeBar
                     && data.EndTime == _lastData.EndTime)
                     return;
@@ -201,4 +202,4 @@
             _dataByType.Clear();
         }
     }
-}+}


Update Program.cs

Update Program.cs

--- ConsoleApp1/ConsoleApp1/Program.cs
+++ ConsoleApp1/ConsoleApp1/Program.cs
@@ -10,7 +10,7 @@
     {
         static void Main(string[] args)
         {
-            /* This code has been edited */
+            // This code has been edited in GitHub
         }
     }
 }


Added tests Write tests G10, G11, G12.

Added tests Write tests G10, G11, G12.

git-svn-id: 1800f71f313d917366f95485fa960eed04b40598@425 33146b6e-df29-0410-a1ca-39be37fb9416

--- Tests/Test_NUnit/WriteTest.cs
+++ Tests/Test_NUnit/WriteTest.cs
@@ -256,7 +256,6 @@
         }

-#if POSTGRES
         public class Northwind1 : Northwind {
           public Northwind1(System.Data.IDbConnection connection)
             : base(connection) { }
@@ -316,16 +315,13 @@
           db.ExecuteCommand("drop table cust1; drop sequence seq8;");
           Assert.IsNotNull(Cust1.CustomerId);
         }
-#endif
-
-
-#if POSTGRES
+
         public class NorthwindG11 : Northwind {
           public NorthwindG11(System.Data.IDbConnection connection)
             : base(connection) { }

-	[System.Data.Linq.Mapping.Table(Name = "rid")]
-	public  class Rid :DbLinq.Linq.IModified {
+         [System.Data.Linq.Mapping.Table(Name = "rid")]
+	       public  class Rid :DbLinq.Linq.IModified {

           [DbLinq.Linq.Mapping.AutoGenId]
@@ -382,7 +378,17 @@
           Assert.AreEqual(Rid.Id,2);
           Assert.AreEqual(Rid.Reanr, 23);
         }
-#endif
+
+        public void G12_EmptyInsertList() {
+          Northwind db = CreateDB();
+          Customer newCust = new Customer();
+          db.Customers.Add(newCust);
+          db.SubmitChanges();
+          Assert.IsNotNull(newCust.CustomerID);
+          db.Customers.Remove(newCust);
+          db.SubmitChanges();
+
+        }

         #endregion


OpCode dictionary initialisation can be tidier again if the ops that take arguments return an action

Makes the operation methods marginally more complicated but the
dictionary initialiser cleaner. But it all function'ly so it must be
cool. ROL(ushort) returns an Action as it takes an argument but ROL_A()
doesn't, it just passes the Accumulator to the ROL Action.

--- DaNES.Emulation/Cpu6502.cs
+++ DaNES.Emulation/Cpu6502.cs
@@ -242,13 +242,13 @@

 			opCodes = new Dictionary<OpCode, Action>
 			{
-				{ OpCode.NOP,        () => NOP()               },
-				{ OpCode.NOP_1,      () => NOP()               },
-				{ OpCode.NOP_2,      () => NOP()               },
-				{ OpCode.NOP_3,      () => NOP()               },
-				{ OpCode.NOP_4,      () => NOP()               },
-				{ OpCode.NOP_5,      () => NOP()               },
-				{ OpCode.NOP_6,      () => NOP()               },
+				{ OpCode.NOP,              NOP                 },
+				{ OpCode.NOP_1,            NOP                 },
+				{ OpCode.NOP_2,            NOP                 },
+				{ OpCode.NOP_3,            NOP                 },
+				{ OpCode.NOP_4,            NOP                 },
+				{ OpCode.NOP_5,            NOP                 },
+				{ OpCode.NOP_6,            NOP                 },
 				{ OpCode.SKB_1,      () => NOP(Immediate())    },
 				{ OpCode.SKB_2,      () => NOP(ZeroPage())     },
 				{ OpCode.SKB_3,      () => NOP(ZeroPage())     },
@@ -296,15 +296,15 @@
 				{ OpCode.JMP_ABS,    () => JMP(Absolute())     },
 				{ OpCode.JMP_IND,    () => JMP(Indirect())     },
 				{ OpCode.JSR,        () => JSR(Absolute())     },
-				{ OpCode.RTS,        () => RTS()               },
-				{ OpCode.RTI,        () => RTI()               },
-				{ OpCode.CLC,        () => CLC()               },
-				{ OpCode.SEC,        () => SEC()               },
-				{ OpCode.CLI,        () => CLI()               },
-				{ OpCode.SEI,        () => SEI()               },
-				{ OpCode.CLV,        () => CLV()               },
-				{ OpCode.CLD,        () => CLD()               },
-				{ OpCode.SED,        () => SED()               },
+				{ OpCode.RTS,              RTS                 },
+				{ OpCode.RTI,              RTI                 },
+				{ OpCode.CLC,              CLC                 },
+				{ OpCode.SEC,              SEC                 },
+				{ OpCode.CLI,              CLI                 },
+				{ OpCode.SEI,              SEI                 },
+				{ OpCode.CLV,              CLV                 },
+				{ OpCode.CLD,              CLD                 },
+				{ OpCode.SED,              SED                 },
 				{ OpCode.BPL,        () => Branch(!Negative)   },
 				{ OpCode.BMI,        () => Branch(Negative)    },
 				{ OpCode.BVC,        () => Branch(!Overflow)   },
@@ -322,20 +322,20 @@
 				{ OpCode.STA_IND_Y,  () => STA(IndirectY())    },
 				{ OpCode.BIT_ZERO,   () => BIT(ZeroPage())     },
 				{ OpCode.BIT_ABS,    () => BIT(Absolute())     },
-				{ OpCode.TXS,        () => TXS()               },
-				{ OpCode.TSX,        () => TSX()               },
-				{ OpCode.PHA,        () => PHA()               },
-				{ OpCode.PLA,        () => PLA()               },
-				{ OpCode.PHP,        () => PHP()               },
-				{ OpCode.PLP,        () => PLP()               },
-				{ OpCode.TAX,        () => TAX()               },
-				{ OpCode.TXA,        () => TXA()               },
-				{ OpCode.DEX,        () => DEX()               },
-				{ OpCode.INX,        () => INX()               },
-				{ OpCode.TAY,        () => TAY()               },
-				{ OpCode.TYA,        () => TYA()               },
-				{ OpCode.DEY,        () => DEY()               },
-				{ OpCode.INY,        () => INY()               },
+				{ OpCode.TXS,              TXS                 },
+				{ OpCode.TSX,              TSX                 },
+				{ OpCode.PHA,              PHA                 },
+				{ OpCode.PLA,              PLA                 },
+				{ OpCode.PHP,              PHP                 },
+				{ OpCode.PLP,              PLP                 },
+				{ OpCode.TAX,              TAX                 },
+				{ OpCode.TXA,              TXA                 },
+				{ OpCode.DEX,              DEX                 },
+				{ OpCode.INX,              INX                 },
+				{ OpCode.TAY,              TAY                 },
+				{ OpCode.TYA,              TYA                 },
+				{ OpCode.DEY,              DEY                 },
+				{ OpCode.INY,              INY                 },
 				{ OpCode.AND_IMD,    () => AND(Immediate())    },
 				{ OpCode.AND_ZERO,   () => AND(ZeroPage())     },
 				{ OpCode.AND_ZERO_X, () => AND(ZeroPageX())    },
@@ -390,22 +390,22 @@
 				{ OpCode.SBC_ABS_Y,  () => SBC(AbsoluteY())    },
 				{ OpCode.SBC_IND_X,  () => SBC(IndirectX())    },
 				{ OpCode.SBC_IND_Y,  () => SBC(IndirectY())    },
-				{ OpCode.LSR_A,      () => LSR_A()             },
+				{ OpCode.LSR_A,            LSR_A               },
 				{ OpCode.LSR_ZERO,   () => LSR(ZeroPage())     },
 				{ OpCode.LSR_ZERO_X, () => LSR(ZeroPageX())    },
 				{ OpCode.LSR_ABS,    () => LSR(Absolute())     },
 				{ OpCode.LSR_ABS_X,  () => LSR(AbsoluteX())    },
-				{ OpCode.ASL_A,      () => ASL_A()             },
+				{ OpCode.ASL_A,            ASL_A               },
 				{ OpCode.ASL_ZERO,   () => ASL(ZeroPage())     },
 				{ OpCode.ASL_ZERO_X, () => ASL(ZeroPageX())    },
 				{ OpCode.ASL_ABS,    () => ASL(Absolute())     },
 				{ OpCode.ASL_ABS_X,  () => ASL(AbsoluteX())    },
-				{ OpCode.ROR_A,      () => ROR_A()             },
+				{ OpCode.ROR_A,            ROR_A               },
 				{ OpCode.ROR_ZERO,   () => ROR(ZeroPage())     },
 				{ OpCode.ROR_ZERO_X, () => ROR(ZeroPageX())    },
 				{ OpCode.ROR_ABS,    () => ROR(Absolute())     },
 				{ OpCode.ROR_ABS_X,  () => ROR(AbsoluteX())    },
-				{ OpCode.ROL_A,      () => ROL_A()             },
+				{ OpCode.ROL_A,            ROL_A               },
 				{ OpCode.ROL_ZERO,   () => ROL(ZeroPage())     },
 				{ OpCode.ROL_ZERO_X, () => ROL(ZeroPageX())    },
 				{ OpCode.ROL_ABS,    () => ROL(Absolute())     },


Added TryReadNodeValues() method to TabstureXmlDocument.

--- Data/TabsterXmlDocument.cs
+++ Data/TabsterXmlDocument.cs
@@ -84,6 +84,21 @@
             return elem != null ? elem.InnerText : defaultValue;
         }

+        public string TryReadNodeValues(string[] names, string defaultValue = null)
+        {
+            foreach (var name in names)
+            {
+                var value = TryReadNodeValue(name);
+
+                if (value != null)
+                {
+                    return value;
+                }
+            }
+
+            return defaultValue;
+        }
+
         public List<XmlNode> ReadChildNodes(string name)
         {
             var nodes = new List<XmlNode>();


Fixes #1. Corrected wrong 'header size' to 'data block size'.

--- DereTore.HCA/HcaDecoder.cs
+++ DereTore.HCA/HcaDecoder.cs
@@ -104,7 +104,7 @@
             if (buffer == null) {
                 throw new ArgumentNullException(nameof(buffer));
             }
-            var minimumSize = GetWaveHeaderNeededLength();
+            var minimumSize = GetWaveDataBlockNeededLength();
             if (buffer.Length < minimumSize) {
                 throw new HcaException(ErrorMessages.GetBufferTooSmall(minimumSize, buffer.Length), ActionResult.BufferTooSmall);
             }


ContentProvider was missing DEBUG conditional compilation flags around some DebugContent calls, which would fail the compiler in release builds.

--- Duality/ContentProvider.cs
+++ Duality/ContentProvider.cs
@@ -449,24 +449,21 @@
 		public static void SetAndroidAssetManager(AssetManager assets)
 		{
 			AndroidAssetManager = assets;
-
+		}
+
+		public static Stream OpenAsset(string path)
+		{
+			try
+			{
+				return AndroidAssetManager.Open(FileHelper.NormalizePath(path));
+			}
+			catch (Exception e)
+			{
 #if DEBUG
-
-#endif
-		}
-
-		public static Stream OpenAsset(string path)
-		{
-			try
-			{
-				return AndroidAssetManager.Open(FileHelper.NormalizePath(path));
-			}
-			catch (Exception e)
-			{
 				var stream = Duality.Android.DebugContent.Open(FileHelper.NormalizePath(path));
 				if(stream != null)
 					return stream;
-
+#endif
 				throw e;
 			}
 		}


Fixed Scene.FindComponent<T>() so that it forwards the activeOnly flag to Scene.FindComponent()

--- Duality/Resources/Scene.cs
+++ Duality/Resources/Scene.cs
@@ -605,7 +605,7 @@
 		/// <returns></returns>
 		public T FindComponent<T>(bool activeOnly = true) where T : class
 		{
-			return FindComponent(typeof(T)) as T;
+			return FindComponent(typeof(T), activeOnly) as T;
 		}
 		/// <summary>
 		/// Finds a single Component of the specified type in this Scene.


Optimized Hatred (thanks BobbyT)

Optimized Hatred (thanks BobbyT)

--- trunk/DefaultCombat/Routines/Advanced/Assassin/Hatred.cs
+++ trunk/DefaultCombat/Routines/Advanced/Assassin/Hatred.cs
@@ -67,13 +67,13 @@

                     //Rotation
                     Spell.Cast("Jolt", ret => Me.CurrentTarget.IsCasting && CombatHotkeys.EnableInterrupts),
-                    Spell.CastOnGround("Death Field"),
-                    Spell.Cast("Creeping Terror", ret => !Me.CurrentTarget.HasDebuff("Creeping Terror")),
-                    Spell.DoT("Discharge", "Crushed (Discharge)"),
                     Spell.Cast("Eradicate", ret => Me.HasBuff("Raze") && Me.Level >= 26),
+                    Spell.CastOnGround("Death Field", ret => !Me.CurrentTarget.HasDebuff("Deathmark") || Me.CurrentTarget.BuffCount("Deathmark") <= 2),
+                    Spell.Cast("Creeping Terror", ret => !Me.CurrentTarget.HasDebuff("Creeping Terror") || Me.CurrentTarget.DebuffTimeLeft("Creeping Terror") <= 2),
+                    Spell.Cast("Discharge", ret => !Me.CurrentTarget.HasDebuff("Discharge") || Me.CurrentTarget.DebuffTimeLeft("Discharge") <= 2),
                     Spell.Cast("Shock", ret => Me.Level < 26),
-                    Spell.Cast("Assassinate", ret => Me.CurrentTarget.HealthPercent <= 30 || Me.HasBuff("Bloodletting")),
-                    Spell.Cast("Leeching Strike", ret => Me.HealthPercent <= 70),
+                    Spell.Cast("Assassinate", ret => Me.HasBuff("Reaper's Rush") || Me.CurrentTarget.HealthPercent <= 30 || Me.HasBuff("Bloodletting")),
+                    Spell.Cast("Leeching Strike", ret => Me.ForcePercent > 40),
                     Spell.Cast("Thrash"),
                     Spell.Buff("Force Speed", ret => Me.CurrentTarget.Distance >= 1.1f && Me.IsMoving && Me.InCombat),

@@ -97,7 +97,7 @@
                         Spell.Cast("Legacy Force Sweep", ret => Me.HasBuff("Heroic Moment") && Me.CurrentTarget.Distance <= 0.5f), //--will only be active when user initiates Heroic Moment--
                         Spell.CastOnGround("Legacy Orbital Strike", ret => Me.HasBuff("Heroic Moment")), //--will only be active when user initiates Heroic Moment--
                         Spell.CastOnGround("Terminate", ret => CombatHotkeys.EnableHK55), //--will only be active when user initiates HK-55 Mode
-                        Spell.DoT("Discharge", "Crushed (Discharge)"),
+                        Spell.DoT("Discharge", "Discharge"),
                         Spell.Cast("Creeping Terror", ret => !Me.CurrentTarget.HasDebuff("Creeping Terror")),
                         Spell.CastOnGround("Death Field"),
                         Spell.Cast("Lacerate", ret => Me.ForcePercent > 70)


mini pull request

mini pull request

--- Startup.cs
+++ Startup.cs
@@ -92,7 +92,7 @@
                 app.UseDeveloperExceptionPage();
             }

-           // TranslationDb.Seed(context);
+          // TranslationDb.Seed(context);

             app.UseDefaultFiles();
             app.UseStaticFiles();


Added ICharacterService to services

Added ICharacterService to services

--- Startup.cs
+++ Startup.cs
@@ -36,6 +36,7 @@

             // DI our Book service in
             services.AddTransient<IBookService, BookService>();
+            services.AddTransient<ICharacterService, CharacterService>();
         }

         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.


Made example the default in debug mode.

Made example the default in debug mode.

--- EdityMcEditface/Program.cs
+++ EdityMcEditface/Program.cs
@@ -18,6 +18,12 @@
             {
                 Environment.CurrentDirectory = Path.GetFullPath(args[0]);
             }
+#if DEBUG
+            else
+            {
+                Environment.CurrentDirectory = "../../Example";
+            }
+#endif
             if(args.Length > 1)
             {
                 string path = "";


Updates the version number to 0.11

Updates the version number to 0.11

--- Version.cs
+++ Version.cs
@@ -24,5 +24,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("0.10.0.0")]
-[assembly: AssemblyFileVersion("0.10.0.0")]+[assembly: AssemblyVersion("0.11.0.0")]
+[assembly: AssemblyFileVersion("0.11.0.0")]


MID 0047 Correction

MID 0047 Correction

--- src/OpenProtocolInterpreter/MIDs/Tool/MID_0047.cs
+++ src/OpenProtocolInterpreter/MIDs/Tool/MID_0047.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace OpenProtocolInterpreter.MIDs.Tool
+namespace OpenProtocolInterpreter.MIDs.Tool
 {
     /// <summary>
     /// MID: Tool Pairing handling
@@ -33,10 +27,20 @@
             this.nextTemplate = nextTemplate;
         }

+        public override string buildPackage()
+        {
+            this.RegisteredDataFields[(int)DataFields.PAIRING_HANDLING_TYPE].Value = (int)this.PairingHandlingType;
+            return base.buildPackage();
+        }
+
         public override MID processPackage(string package)
         {
             if (base.isCorrectType(package))
-                return base.processPackage(package);
+            {
+                base.processPackage(package);
+                this.PairingHandlingType = (PairingHandlingTypes)this.RegisteredDataFields[(int)DataFields.PAIRING_HANDLING_TYPE].ToInt32();
+                return this;
+            }

             return this.nextTemplate.processPackage(package);
         }


Adding Unit Test to very case insensitive behavior

--HG--
branch : dev

--- src/Orchard.Tests/Commands/CommandHandlerTests.cs
+++ src/Orchard.Tests/Commands/CommandHandlerTests.cs
@@ -76,6 +76,14 @@
         }

         [Test]
+        public void TestCaseInsensitiveForCommand() {
+            var commandContext = CreateCommandContext("BAZ", new Dictionary<string, string> { { "VERBOSE", "true" } });
+            _handler.Execute(commandContext);
+            Assert.That(commandContext.Output.ToString(), Is.EqualTo("Command Baz Called : This was a test"));
+        }
+
+
+        [Test]
         public void TestBooleanSwitchForCommand() {
             var commandContext = CreateCommandContext("Baz", new Dictionary<string, string> {{"Verbose", "true"}});
             _handler.Execute(commandContext);


Make the context menu key work in variable explorer.

--- src/Package/Impl/DataInspect/VariableView.xaml.cs
+++ src/Package/Impl/DataInspect/VariableView.xaml.cs
@@ -174,12 +174,7 @@
                     return;
                 case Key.System:
                     if (e.SystemKey == Key.F10 && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) {
-                        var focus = Keyboard.FocusedElement as FrameworkElement;
-                        if (focus != null) {
-                            var pt = focus.PointToScreen(new Point(1, 1));
-                            _shell.ShowContextMenu(
-                                new CommandID(RGuidList.RCmdSetGuid, (int)RContextMenuId.VariableExplorer), (int)pt.X, (int)pt.Y, this);
-                        }
+                        ShowContextMenu();
                     }
                     break;
                 case Key.C:
@@ -194,6 +189,15 @@
                     break;
             }
             base.OnPreviewKeyDown(e);
+        }
+
+        private void ShowContextMenu() {
+            var focus = Keyboard.FocusedElement as FrameworkElement;
+            if (focus != null) {
+                var pt = focus.PointToScreen(new Point(1, 1));
+                _shell.ShowContextMenu(
+                    new CommandID(RGuidList.RCmdSetGuid, (int)RContextMenuId.VariableExplorer), (int)pt.X, (int)pt.Y, this);
+            }
         }

         protected override void OnPreviewKeyUp(KeyEventArgs e) {
@@ -206,6 +210,8 @@
                 return;
             } else if (e.Key == Key.Delete || e.Key == Key.Back) {
                 DeleteCurrentVariableAsync().DoNotWait();
+            } else if (e.Key == Key.Apps) {
+                ShowContextMenu();
             }
             base.OnPreviewKeyUp(e);
         }


Fix deadlock caused by mix of sync and async code execution (#15)

--- src/Pomelo.Extensions.Caching.MySql/MySqlCache.cs
+++ src/Pomelo.Extensions.Caching.MySql/MySqlCache.cs
@@ -102,7 +102,7 @@

 			var value = _dbOperations.GetCacheItem(key);

-			ScanForExpiredItemsIfRequired().Wait();
+			ScanForExpiredItemsIfRequired();

 			return value;
 		}
@@ -117,7 +117,7 @@
 			token.ThrowIfCancellationRequested();

             var value = await _dbOperations.GetCacheItemAsync(key, token: token);
-			await ScanForExpiredItemsIfRequired();
+			await ScanForExpiredItemsIfRequiredAsync();

 			return value;
 		}
@@ -131,7 +131,7 @@

 			_dbOperations.RefreshCacheItem(key);

-			ScanForExpiredItemsIfRequired().Wait();
+			ScanForExpiredItemsIfRequired();
 		}

         public async Task RefreshAsync(string key, CancellationToken token = default(CancellationToken))
@@ -145,7 +145,7 @@

             await _dbOperations.RefreshCacheItemAsync(key, token: token);

-			await ScanForExpiredItemsIfRequired();
+			await ScanForExpiredItemsIfRequiredAsync();
 		}

 		public void Remove(string key)
@@ -157,7 +157,7 @@

 			_dbOperations.DeleteCacheItem(key);

-			ScanForExpiredItemsIfRequired().Wait();
+			ScanForExpiredItemsIfRequired();
 		}

         public async Task RemoveAsync(string key, CancellationToken token = default(CancellationToken))
@@ -171,7 +171,7 @@

             await _dbOperations.DeleteCacheItemAsync(key, token: token);

-			await ScanForExpiredItemsIfRequired();
+			await ScanForExpiredItemsIfRequiredAsync();
 		}

 		public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
@@ -195,7 +195,7 @@

 			_dbOperations.SetCacheItem(key, value, options);

-			ScanForExpiredItemsIfRequired().Wait();
+			ScanForExpiredItemsIfRequired();
 		}

         public async Task SetAsync(
@@ -225,12 +225,12 @@

             await _dbOperations.SetCacheItemAsync(key, value, options, token);

-			await ScanForExpiredItemsIfRequired();
+			await ScanForExpiredItemsIfRequiredAsync();
 		}

 		// Called by multiple actions to see how long it's been since we last checked for expired items.
 		// If sufficient time has elapsed then a scan is initiated on a background task.
-		private async Task ScanForExpiredItemsIfRequired()
+		private async Task ScanForExpiredItemsIfRequiredAsync()
 		{
 			var utcNow = _systemClock.UtcNow;
 			// TODO: Multiple threads could trigger this scan which leads to multiple calls to database.
@@ -243,6 +243,16 @@

 				//Task.Delay(1000);
 				await Task.Run(_deleteExpiredCachedItemsDelegate);
+			}
+		}
+
+		private void ScanForExpiredItemsIfRequired()
+		{
+			var utcNow = _systemClock.UtcNow;
+			if ((utcNow - _lastExpirationScan) > _expiredItemsDeletionInterval)
+			{
+				_lastExpirationScan = utcNow;
+				_deleteExpiredCachedItemsDelegate.Invoke();
 			}
 		}


CommandLineTests: document bug when reparsing

--- src/Kirkin.Tests/CommandLine/CommandLineTests.cs
+++ src/Kirkin.Tests/CommandLine/CommandLineTests.cs
@@ -30,10 +30,25 @@

             ICommand command = parser.Parse("sync --subscription main /VALIDATE TRUE".Split(' '));

+            Assert.Null(subscription);
+            Assert.False(validate);
+
             command.Execute();

             Assert.AreEqual("main", subscription);
             Assert.True(validate);
+
+            command = parser.Parse("sync --subscription extra".Split(' '));
+
+            Assert.AreEqual("main", subscription);
+            Assert.True(validate);
+
+            validate = false; // Reset.
+
+            command.Execute();
+
+            Assert.AreEqual("extra", subscription);
+            Assert.False(validate); // Bug.

             //Command sync = new Command("sync");
             //bool verify = false;


remove \r\n's

remove \r\n's

svn path=/trunk/banshee/; revision=4037

--- src/Libraries/Hyena.Gui/Hyena.Data.Gui/Column.cs
+++ src/Libraries/Hyena.Gui/Hyena.Data.Gui/Column.cs
@@ -139,24 +139,24 @@
             set { header_cell = value; }
         }

-        public int MinWidth {
-            get { return minWidth; }
-            set { minWidth = value; }
-        }
-
-        internal double MinRelativeWidth {
-            get { return minRelativeWidth; }
+        public int MinWidth {
+            get { return minWidth; }
+            set { minWidth = value; }
+        }
+
+        internal double MinRelativeWidth {
+            get { return minRelativeWidth; }
             set { minRelativeWidth = value; }
         }

         public int MaxWidth {
             get { return maxWidth; }
             set { maxWidth = value; }
-        }
-
-        public double RelativeWidth {
-            get { return relativeWidth; }
-            set { relativeWidth = value; }
+        }
+
+        public double RelativeWidth {
+            get { return relativeWidth; }
+            set { relativeWidth = value; }
         }

         public string Id {


Update assembly version

Update assembly version

--- src/NetworkManagement/Properties/AssemblyInfo.cs
+++ src/NetworkManagement/Properties/AssemblyInfo.cs
@@ -20,7 +20,7 @@
 [assembly: AssemblyDescription("Provides management functionality for Microsoft Azure Network.")]

 [assembly: AssemblyVersion("4.0.0.0")]
-[assembly: AssemblyFileVersion("4.1.0.0")]
+[assembly: AssemblyFileVersion("4.2.0.0")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Microsoft")]
 [assembly: AssemblyProduct("Azure .NET SDK")]


feat(PopupPlatformIos): Added explanations in a comment for #459

--- src/Rg.Plugins.Popup.IOS/Impl/PopupPlatformIos.cs
+++ src/Rg.Plugins.Popup.IOS/Impl/PopupPlatformIos.cs
@@ -19,6 +19,7 @@
     [Preserve(AllMembers = true)]
     internal class PopupPlatformIos : IPopupPlatform
     {
+        // It's necessary because GC in Xamarin.iOS 13 removes all UIWindow if there are not any references to them. See #459
         readonly List<UIWindow> _windows = new List<UIWindow>();

         bool IsiOS9OrNewer => UIDevice.CurrentDevice.CheckSystemVersion(9, 0);


Start up the HTTP server earlier so we can catch HTTP.SYS bullshit

--- src/Shimmer.Tests/Client/DownloadReleasesTests.cs
+++ src/Shimmer.Tests/Client/DownloadReleasesTests.cs
@@ -2,6 +2,7 @@
 using System.IO;
 using System.IO.Abstractions;
 using System.Linq;
+using System.Net;
 using System.Reactive.Linq;
 using System.Text;
 using Moq;
@@ -118,7 +119,15 @@

             var updateDir = new DirectoryInfo(IntegrationTestHelper.GetPath("..", "SampleUpdatingApp", "SampleReleasesFolder"));

-            var httpServer = new StaticHttpServer(30405, updateDir.FullName);
+            IDisposable disp;
+            try {
+                var httpServer = new StaticHttpServer(30405, updateDir.FullName);
+                disp = httpServer.Start();
+            }
+            catch (HttpListenerException) {
+                Assert.False(true, @"Windows sucks, go run 'netsh http add urlacl url=http://+:30405/ user=MYMACHINE\MyUser");
+                return;
+            }

             var entriesToDownload = updateDir.GetFiles("*.nupkg")
                 .Select(x => ReleaseEntry.GenerateFromFile(x.FullName))
@@ -126,7 +135,7 @@

             entriesToDownload.Count().ShouldBeGreaterThan(0);

-            using (httpServer.Start())
+            using (disp)
             using (Utility.WithTempDirectory(out tempDir)) {
                 // NB: This is normally done by CheckForUpdates, but since
                 // we're skipping that in the test we have to do it ourselves


Add a setting to parent all targets directly under the project.

--- src/StructuredLogger/Construction/Construction.cs
+++ src/StructuredLogger/Construction/Construction.cs
@@ -224,6 +224,8 @@
                 Intern(args.TargetFile));
         }

+        public static bool ParentAllTargetsUnderProject { get; set; }
+
         private void AddTargetCore(BuildEventArgs args, string targetName, string parentTargetName, string targetFile)
         {
             try
@@ -235,7 +237,7 @@
                     target.NodeId = args.BuildEventContext.NodeId;
                     target.StartTime = args.Timestamp;

-                    if (!string.IsNullOrEmpty(parentTargetName))
+                    if (!ParentAllTargetsUnderProject && !string.IsNullOrEmpty(parentTargetName))
                     {
                         var parentTarget = project.GetOrAddTargetByName(parentTargetName);
                         parentTarget.TryAddTarget(target);


POI：add unit test for SXSSFSheet#changeRowNum

--- testcases/ooxml/XSSF/Streaming/TestSXSSFSheet.cs
+++ testcases/ooxml/XSSF/Streaming/TestSXSSFSheet.cs
@@ -159,5 +159,23 @@
         public void CreateRowAfterLastRow() {
             createRowAfterLastRow(SpreadsheetVersion.EXCEL2007);
         }
+
+        [Test]
+        public void ChangeRowNum()
+        {
+            SXSSFWorkbook wb = new SXSSFWorkbook(3);
+            SXSSFSheet sheet = wb.CreateSheet() as SXSSFSheet;
+            SXSSFRow row0 = sheet.CreateRow(0) as SXSSFRow;
+            SXSSFRow row1 = sheet.CreateRow(1) as SXSSFRow;
+            sheet.ChangeRowNum(row0, 2);
+
+            Assert.AreEqual(1, row1.RowNum, "Row 1 knows its row number");
+            Assert.AreEqual(2, row0.RowNum, "Row 2 knows its row number");
+            Assert.AreEqual(1, sheet.GetRowNum(row1), "Sheet knows Row 1's row number");
+            Assert.AreEqual(2, sheet.GetRowNum(row0), "Sheet knows Row 2's row number");
+            Assert.AreEqual(row1, sheet.GetEnumerator().Current, "Sheet row iteratation order should be ascending");
+
+            wb.Close();
+        }
     }
 }


Fixed ApplyPropertyChangeAttribute test to fit new api.

--- Models/Models.Tests/Evolution/ChangeApplyTests.cs
+++ Models/Models.Tests/Evolution/ChangeApplyTests.cs
@@ -90,7 +90,9 @@
         {
             var parent = railway.Routes.First().Entry;
             var newValue = Signal.FAILURE;
-            var change = new PropertyChangeAttribute<Signal>(parent.AbsoluteUri, "Signal", newValue);
+            var oldValue = repository.Resolve(parent.AbsoluteUri).GetType().GetProperty("Signal").GetValue(parent, null);
+
+            var change = new PropertyChangeAttribute<Signal>(parent.AbsoluteUri, "Signal", (Signal)oldValue, newValue);

             change.Apply(repository);


New device list parser test based on user submitted data


Subversion\Svn.cs: minor updates

Subversion\Svn.cs: minor updates

--- Releases/4.0.5.0/Main/Framework/Subversion/Svn.cs
+++ Releases/4.0.5.0/Main/Framework/Subversion/Svn.cs
@@ -5,11 +5,9 @@
 namespace MSBuild.ExtensionPack.Subversion
 {
     using System;
-    using System.Diagnostics;
     using System.Globalization;
     using System.IO;
     using System.Linq;
-    using System.Text;
     using System.Text.RegularExpressions;
     using System.Xml.Serialization;
     using Microsoft.Build.Framework;
@@ -20,8 +18,8 @@
     /// Valid TaskActions are:
     /// <para>Version (Required: Item Output: Info)</para>
     /// <para>Info (Required: Item Output: Info)</para>
-    /// <para>GetProperty (Required: Item, PropertyName Output: PropertyValue</para>
-    /// <para>SetProperty (Required: Item, PropertyName, PropertyValue</para>
+    /// <para>GetProperty (Required: Item, PropertyName Output: PropertyValue)</para>
+    /// <para>SetProperty (Required: Item, PropertyName, PropertyValue)</para>
     /// <para>Checkout (Required: Items, Destination)</para>
     /// <para>Update (Required: Items)</para>
     /// <para>Add (Required: Items)</para>
@@ -485,11 +483,11 @@
                 this.Info = new TaskItem(this.Item);
                 this.Info.SetMetadata("MinRevision", m.Groups["min"].Value);
                 this.Info.SetMetadata("MaxRevision", m.Groups[mixed ? "max" : "min"].Value);
-                this.Info.SetMetadata("IsMixed", mixed.ToString());
-                this.Info.SetMetadata("IsModified", sw.Contains("M").ToString());
-                this.Info.SetMetadata("IsSwitched", sw.Contains("S").ToString());
-                this.Info.SetMetadata("IsPartial", sw.Contains("P").ToString());
-                this.Info.SetMetadata("IsClean", (!mixed && sw.Length == 0).ToString());
+                this.Info.SetMetadata("IsMixed", mixed.ToString(CultureInfo.InvariantCulture));
+                this.Info.SetMetadata("IsModified", sw.Contains("M").ToString(CultureInfo.InvariantCulture));
+                this.Info.SetMetadata("IsSwitched", sw.Contains("S").ToString(CultureInfo.InvariantCulture));
+                this.Info.SetMetadata("IsPartial", sw.Contains("P").ToString(CultureInfo.InvariantCulture));
+                this.Info.SetMetadata("IsClean", (!mixed && sw.Length == 0).ToString(CultureInfo.InvariantCulture));
             }
         }


Implement random walk for 2D

Implement random walk for 2D

--- MathSample/RandomWalkConsole/Program.cs
+++ MathSample/RandomWalkConsole/Program.cs
@@ -1,8 +1,7 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;

 namespace RandomWalkConsole
 {
@@ -10,6 +9,28 @@
     {
         static void Main(string[] args)
         {
+            var unfinished = Enumerable.Range(0, 1000)
+                .Select(_ => Walk2())
+                .Aggregate(0, (u, t) => u + (t.HasValue ? 0 : 1));
+            Console.WriteLine(unfinished);
+        }
+
+        static readonly Random random = new Random();
+        static readonly Int32Vector3[] Directions2 = new[] { Int32Vector3.XBasis, Int32Vector3.YBasis, -Int32Vector3.XBasis, -Int32Vector3.YBasis };
+
+        static int? Walk2()
+        {
+            var current = Int32Vector3.Zero;
+
+            for (var i = 1; i <= 1000000; i++)
+            {
+                current += Directions2[random.Next(0, Directions2.Length)];
+
+                if (current == Int32Vector3.Zero) return i;
+            }
+
+            Console.WriteLine(current);
+            return null;
         }
     }
 }


minor changes

minor changes

--- DBLike/Client/Threads/PollFiles.cs
+++ DBLike/Client/Threads/PollFiles.cs
@@ -59,8 +59,9 @@

         public void poll()
         {
+            Configuration.flag.polling = true;
             Program.ClientForm.addtoConsole("Poll initiated");
-            Configuration.flag.polling = true;
+
             //MessageBox.Show("Polling started", "Client");
             try
             {


AdventureSample - fix null ref bug in Examine

--- projects/AdventureSample/src/Adventure/adventure.cs
+++ projects/AdventureSample/src/Adventure/adventure.cs
@@ -401,7 +401,7 @@
         {
             ObjectRef obj = objects.Find(noun);

-            if ((obj.Room != map.CurrentRoom) && (obj.Room != RoomId.Inventory))
+            if ((obj == null) || ((obj.Room != map.CurrentRoom) && (obj.Room != RoomId.Inventory)))
             {
                 PRINT("IT'S NOT HERE!");
             }


Webcam api port

Webcam api port

--- RemoteTaskServer/Api/UlteriusApiServer.cs
+++ RemoteTaskServer/Api/UlteriusApiServer.cs
@@ -45,7 +45,7 @@
             AllClients = new ConcurrentDictionary<Guid, AuthClient>();
             ScreenShareService = new ScreenShareService();
             var address = NetworkService.GetAddress();
-            var endPoints = new List<IPEndPoint> {new IPEndPoint(address, apiPort)};
+            var endPoints = new List<IPEndPoint> {new IPEndPoint(address, apiPort), new IPEndPoint(address, 22010) };
             var server = new WebSocketEventListener(endPoints, new WebSocketListenerOptions
             {
                 PingTimeout = TimeSpan.FromSeconds(15),


Fixed wpf scroll behaviour

Fixed wpf scroll behaviour

--- ReoGrid/Views/NormalViewportController.cs
+++ ReoGrid/Views/NormalViewportController.cs
@@ -884,16 +884,16 @@

 			if ((dir & ScrollDirection.Horizontal) == ScrollDirection.Horizontal)
 			{
-				if (scrollHorValue + x > scrollHorMax - scrollHorLarge)
-					x = scrollHorMax - scrollHorLarge - scrollHorValue;
+				if (scrollHorValue + x > scrollHorMax)
+					x = scrollHorMax - scrollHorValue;
 				if (scrollHorValue + x < scrollHorMin)
 					x = scrollHorMin - scrollHorValue;
 			}

 			if ((dir & ScrollDirection.Vertical) == ScrollDirection.Vertical)
 			{
-				if (scrollVerValue + y > scrollVerMax - scrollVerLarge)
-					y = scrollVerMax - scrollVerLarge - scrollVerValue;
+				if (scrollVerValue + y > scrollVerMax)
+					y = scrollVerMax - scrollVerValue;
 				if (scrollVerValue + y < scrollVerMin)
 					y = scrollVerMin - scrollVerValue;
 			}
@@ -1079,25 +1079,25 @@

 			if (worksheet.cols.Count > 0)
 			{
-				width = worksheet.cols[worksheet.cols.Count - 1].Right + mainViewport.Width - mainViewport.Width / scale + 1;
+				width = worksheet.cols[worksheet.cols.Count - 1].Right + -mainViewport.Width;
 			}

 			if (worksheet.rows.Count > 0)
 			{
-				height = worksheet.rows[worksheet.rows.Count - 1].Bottom + mainViewport.Height - mainViewport.Height / scale + 1;
-			}
-
-			if (this.worksheet.controlAdapter != null
-				&& this.worksheet.controlAdapter.ControlInstance != null
-				&& this.worksheet.controlAdapter.ControlInstance.ShowScrollEndSpacing
-				&& this.worksheet.FreezeArea == FreezeArea.None)
-			{
-				width += 100 / scale;
-				height += 100 / scale;
-			}
-
-			int maxHorizontal = (int)(Math.Round(width + this.mainViewport.Left));
-			int maxVertical = Math.Max(0, (int)(Math.Round(height + this.mainViewport.Top)));
+				height = worksheet.rows[worksheet.rows.Count - 1].Bottom + -mainViewport.Height;
+			}
+
+			//if (this.worksheet.controlAdapter != null
+			//	&& this.worksheet.controlAdapter.ControlInstance != null
+			//	&& this.worksheet.controlAdapter.ControlInstance.ShowScrollEndSpacing
+			//	&& this.worksheet.FreezeArea == FreezeArea.None)
+			//{
+			//	width += 100 / scale;
+			//	height += 100 / scale;
+			//}
+
+			int maxHorizontal = (int)(Math.Round(width));
+			int maxVertical = Math.Max(0, (int)(Math.Round(height)));

 #if WINFORM || ANDROID
 			int offHor = maxHorizontal - this.scrollHorMax;


Fix crash on loading save with sling dropped.

--- Trunk/GameEngine/Level/Map.cs
+++ Trunk/GameEngine/Level/Map.cs
@@ -336,9 +336,9 @@
             {
                 string typeString = reader.ReadElementContentAsString();
                 Item newItem = CoreGameEngine.Instance.ItemFactory.CreateItem(typeString);
+                newItem.ReadXml(reader);
                 Point position = new Point();
                 position = position.ReadXml(reader);
-                newItem.ReadXml(reader);
                 m_items.Add(new Pair<Item, Point>(newItem, position));
             });
             ListSerialization.ReadListFromXML(reader, readDelegate);


Use while loop instead of recursion. Some refactoring to remove repeated code.

--- TwitchGameAutomate/Program.cs
+++ TwitchGameAutomate/Program.cs
@@ -4,7 +4,10 @@
 using System.IO;
 using System.Diagnostics;
 using System.Collections.Generic;
+using System.Net;
 using System.Security.Cryptography;
+using System.Threading;
+using TwitchAutomator.Properties;

 namespace TwitchAutomator
 {
@@ -12,155 +15,102 @@
     {

         private static List<string> _games;
+        private static string _token;

         static void Main(string[] args)
         {
+            VersionChecks();
+            GetOauthToken();

-            versionChecks();
-            // Get details.
-            getGame();
-
+            // Our games list
+            _games = new List<string>(File.ReadAllLines(@"./gameslist.dat"));
+
+            while (true)
+            {
+                FindGameWindow();
+            }
         }
-
-        static void getGame()
+
+        static void GetOauthToken()
         {
-            _games = new List<string>(File.ReadAllLines(@"./gameslist.dat")); // Our games list
-            try
+            Console.WriteLine("Fetching Twitch Details");
+            Console.WriteLine("A page will open up requesting authorisation to your twitch account, this is so we can update your details.");
+            Process.Start("https://api.twitch.tv/kraken/oauth2/authorize?response_type=token&client_id=9xcf5l6r7kipl9d0mkmnjltoo8y3wv9&scope=channel_editor&redirect_uri=http://twitch.seanodonnell.co.uk");
+            Console.WriteLine("Please copy and paste in the token you got from the website you just visited, this is your OAuth key and must not be shared with anyone.");
+            _token = Console.ReadLine();
+            Console.Clear();
+            Console.WriteLine("Console Cleared to avoid Token Leaks");
+        }
+
+        static void FindGameWindow()
+        {
+            bool gameFound = false;
+
+            foreach (Process p in Process.GetProcesses()) // For each process we have running
             {
-                foreach (Process p in System.Diagnostics.Process.GetProcesses()) // For each process we have running
+                if (_games.Contains(p.MainWindowTitle)) // If the title is within our games list, that user is likely playing that game.
                 {
-                    if (p.MainWindowTitle != null) // Exclude ones with no main window (Likely system processes)
-                    {
-                        if (_games.Contains(p.MainWindowTitle)) // If the title is within our games list, that user is likely playing that game.
-                        {
-                            updateTwitch(p.MainWindowTitle);
-                        }
-                    }
+                    gameFound = true;
+                    SetGame(p.MainWindowTitle);
+                    Thread.Sleep(Settings.Default.refreshtime);
+                    break;
                 }
-
-            }
-                catch (Exception ex)
-            {
-
             }

-            Console.WriteLine("We couldn't find any games. Retrying in 5 seconds.");
-            System.Threading.Thread.Sleep(5000);
-            getGame();
-        }
-        static void updateTwitch(string game)
-        {
-            string token;
-            Console.WriteLine("Fetching Twitch Details");
-            Console.WriteLine("A page will open up requesting authorisation to your twitch account, this is so we can update your details.");
-            System.Diagnostics.Process.Start("https://api.twitch.tv/kraken/oauth2/authorize?response_type=token&client_id=9xcf5l6r7kipl9d0mkmnjltoo8y3wv9&scope=channel_editor&redirect_uri=http://twitch.seanodonnell.co.uk");
-            Console.WriteLine("Please copy and paste in the token you got from the website you just visited, this is your OAuth key and must not be shared with anyone.");
-            token = Console.ReadLine();
-            Console.Clear();
-            Console.WriteLine("Console Cleared to avoid Token Leaks");
-            Console.WriteLine("Please input your Twitch Channel Name");
-
-            if (string.IsNullOrEmpty(Properties.Settings.Default.twitchname))
+            if (!gameFound)
             {
-                Properties.Settings.Default.twitchname = Console.ReadLine();
-                Properties.Settings.Default.Save();
+                Console.WriteLine("We couldn't find any games. Retrying in 5 seconds.");
+                Thread.Sleep(5000);
             }
-            string cGame = checkGame(game);
-            string cTitle = checkTitle(game);
-            if (cTitle != "unchanged")
-            {
-                TwitchApi.UpdateStreamTitle(cTitle, Properties.Settings.Default.twitchname, token);
-            }
-            TwitchApi.UpdateStreamGame(cGame, Properties.Settings.Default.twitchname, token);
-
-            Console.WriteLine("I have updated the game to " + cGame);
-            refresh(game, token, Properties.Settings.Default.twitchname);

         }

-        static void refresh(string game,string token, string channelname)
+        static void SetGame(string game)
         {
-            if(Properties.Settings.Default.refreshtime == 0) //If it's not been set then then.... we can try set it.
+            if (string.IsNullOrEmpty(Settings.Default.twitchname))
+            {
+                Console.WriteLine("Please input your Twitch Channel Name");
+                Settings.Default.twitchname = Console.ReadLine();
+                Settings.Default.Save();
+            }
+
+            UpdateTwitch(game);
+
+            if (Settings.Default.refreshtime == 0) //If it's not been set then then.... we can try set it.
             {
                 Console.WriteLine("How often do you want us to refresh? (Time in minutes)");
                 int minutes = Convert.ToInt32(Console.ReadLine());
                 int milliseconds = minutes * 60000;
-                Properties.Settings.Default.refreshtime = milliseconds;
-                Properties.Settings.Default.Save();
+                Settings.Default.refreshtime = milliseconds;
+                Settings.Default.Save();
             }
-            Console.WriteLine("We will refresh every " + Properties.Settings.Default.refreshtime / 60000 + " Minutes" );
-
-            System.Threading.Thread.Sleep(Properties.Settings.Default.refreshtime);
-            refreshGetGame(token);
+            Console.WriteLine("We will refresh every " + Settings.Default.refreshtime / 60000 + " Minutes");

         }

-        static void refreshTwitch(string game, string sid, string mid, string token, string channelname)
+        static void UpdateTwitch(string game)
         {
-            string cGame = checkGame(game);
-            string cTitle = checkTitle(game);
-            if(cTitle != "unchanged")
+            string cGame = CheckGame(game);
+            string cTitle = CheckTitle(game);
+            if (cTitle != "unchanged")
             {
-                TwitchApi.UpdateStreamTitle(cTitle, channelname, token);
+                TwitchApi.UpdateStreamTitle(cTitle, Settings.Default.twitchname, _token);
             }
-            TwitchApi.UpdateStreamGame(cGame, channelname, token);
+            TwitchApi.UpdateStreamGame(cGame, Settings.Default.twitchname, _token);
+
             Console.WriteLine("I have updated the game to " + cGame);
         }

-        static void refreshUpdateTwitch(string game, string token)
-        {

-            string cGame = checkGame(game);
-            string cTitle = checkTitle(game);
-            if (cTitle != "unchanged")
-            {
-                TwitchApi.UpdateStreamTitle(cTitle, Properties.Settings.Default.twitchname, token);
-            }
-            TwitchApi.UpdateStreamGame(cGame, Properties.Settings.Default.twitchname, token);
-
-            Console.WriteLine("I have updated the game to " + cGame);
-            refresh(game, token, Properties.Settings.Default.twitchname);
-
-        }
-
-        static void refreshGetGame(string token)
-        {
-            _games = new List<string>(File.ReadAllLines(@"./gameslist.dat")); // Our games list
-            try
-            {
-                foreach (Process p in System.Diagnostics.Process.GetProcesses()) // For each process we have running
-                {
-                    if (p.MainWindowTitle != null) // Exclude ones with no main window (Likely system processes)
-                    {
-                        if (_games.Contains(p.MainWindowTitle)) // If the title is within our games list, that user is likely playing that game.
-                        {
-
-                            refreshUpdateTwitch(p.MainWindowTitle, token);
-
-
-                        }
-                    }
-                }
-
-            }
-            catch (Exception ex)
-            {
-
-            }
-
-            Console.WriteLine("We couldn't find any games. Retrying in 5 seconds.");
-            System.Threading.Thread.Sleep(5000);
-            getGame();
-        }
         // Will compare the game we have detected against the list of games in the games.txt file
-        static string checkGame(string game)
+        static string CheckGame(string game)
         {
             // Local Variable so we don't mess with the other one.
             string cGame = game;
             var path = Path.Combine(Directory.GetCurrentDirectory(), "games.txt"); // Get our path to the games list. (JSON)
             JObject result = JObject.Parse(File.ReadAllText(path));
             // If the result is in the list. Then we will return the correct title.
-            if(result["games"][game] != null)
+            if (result["games"][game] != null)
             {
                 Console.WriteLine("I have corrected the game to a custom one");
                 cGame = result["games"][game]["name"].ToString();
@@ -173,7 +123,7 @@
         }

         // Will compare the game we have detected to the list of titles that should be set in the games.txt file.
-        static string checkTitle(string game)
+        static string CheckTitle(string game)
         {
             string cTitle;
             var path = Path.Combine(Directory.GetCurrentDirectory(), "games.txt"); // Get our path to the games list. (JSON)
@@ -187,24 +137,22 @@
                 cTitle = result["games"][game]["title"].ToString();
                 return cTitle;
             }
-            else
-            {
-                Console.WriteLine("Couldn't find game. We will not modify your title.");
-                return "unchanged";
-            }
+
+            Console.WriteLine("Couldn't find game. We will not modify your title.");
+            return "unchanged";
         }

-        static void versionChecks()
+        static void VersionChecks()
         {
             // Version Checks
             var path = Directory.GetCurrentDirectory() + "/TwitchAutomator.exe"; // Path to the EXE
             var file = File.OpenRead(path); // Opens file
             var appmd5 = MD5.Create().ComputeHash(file); // Creates the MD5 Of the file
             var cMD5 = BitConverter.ToString(appmd5).Replace("-", "").ToLower(); // Converts our computed hash to a string and replaces the - with nothing and puts it lowercase for easier comparing.
+
             // Call my website to see if the version is the same...
-            System.Net.WebClient wc = new System.Net.WebClient();
-            byte[] sMD5 = wc.DownloadData("http://seanodonnell.co.uk/twitch/versioncheck.txt"); // Download the md5 from the site.
-            string uMD5 = System.Text.Encoding.UTF8.GetString(sMD5); // Convert it to a string.
+            var wc = new WebClient();
+            string uMD5 = wc.DownloadString("http://seanodonnell.co.uk/twitch/versioncheck.txt"); // Download the md5 from the site.
             if (uMD5 != cMD5)
             {
                 Console.WriteLine("This is an out of date version, please redownload the bot!"); // Tell user to redownload


User nick click fix;

User nick click fix;

--- UI/ViewModel/UserViewModel.cs
+++ UI/ViewModel/UserViewModel.cs
@@ -102,7 +102,7 @@
     #region command methods
     private void UserClick(object obj)
     {
-      _parent.Message += UserId + ", ";
+      _parent.Message += UserId.Nick + ", ";
       _parent.MessageCaretIndex = _parent.Message.Length;
     }


Wrote first lines of Document#Save method.

--- Uiml/Gummy/Kernel/Document.cs
+++ Uiml/Gummy/Kernel/Document.cs
@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 using System.IO;
+using System.Xml;

 using Uiml.Gummy.Domain;

@@ -43,6 +44,8 @@

         public void Save(Stream s)
         {
+            XmlTextWriter xmlw = new XmlTextWriter(s, null);
+            xmlw.Formatting = Formatting.Indented;
         }
     }
 }


More notes on admin titles

More notes on admin titles

--- Views/Admin/PersonList.cshtml
+++ Views/Admin/PersonList.cshtml
@@ -2,8 +2,9 @@
     DisplayAsync helper to display these shapes. *@

 @model IEnumerable<dynamic>
-@* Titles displayed on the admin need to be wrapped in such a <zone> to be properly displayed. You don't need to do this
-    for titles on the frontend. *@
+@* Titles displayed on the admin need to be wrapped in such a <zone> to be properly displayed (this way they can also be
+    displayed in the top bar of the admin theme, something you can enable under Configuration -> Settings -> Admin.) You
+    don't need to do this for titles on the frontend. *@
 <zone Name="Title">
     @* Note how we use RenderTitleSegments() here. It'll show the title here that might have been collaboratively
         modified by multiple pieces of code (like adding suffixes, section names), and most importantly, it'll also add


#49 Totale distance - gestion miles/km + arrondi

--- WUI/Views/Race/Details.cshtml
+++ WUI/Views/Race/Details.cshtml
@@ -145,14 +145,18 @@
                                                 + '' + route.legs[i].distance.text + '	'
                                                 + '
';

-                        //Distance totale du parcours : divisé par 1000 -> en km
-                        totalDistances += route.legs[i].distance.value / 1000;
+                        //Distance totale du parcours
+                        if (KmOrMiles == "Miles") {
+                            totalDistances += (route.legs[i].distance.value / 1000) * 0.621371;
+                        } else {
+                            totalDistances += route.legs[i].distance.value / 1000;
+                        }
                     }
                     summaryPanel.innerHTML += '
'
                                                 + '	'
                                                 + '	'
                                                 + ' Distance Totale 	'
-                                                + '' + totalDistances + ' km 	'
+                                                + '' + totalDistances.toFixed(1) + ' ' + KmOrMiles + '	'
                                                 + '
';
                 }
             });


Switch to lower case URLs

Switch to lower case URLs

--- Dashboard/App_Start/RouteConfig.cs
+++ Dashboard/App_Start/RouteConfig.cs
@@ -11,6 +11,8 @@
     {
         public static void RegisterRoutes(RouteCollection routes)
         {
+            routes.LowercaseUrls = true;
+
             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

             routes.MapRoute(


DB: Load Classification last to improve performance

--- Database/DataLoader/CsvImporter.cs
+++ Database/DataLoader/CsvImporter.cs
@@ -20,9 +20,13 @@
         /// <param name="dirName">Full path name of the root directory</param>
         /// <param name="dbContext">Shared instance of DbContextWrapper</param>
         public static void LoadAll(string dirName, DbContextWrapper dbContext) {
-            LoadAppend(Path.Combine(dirName, "append"), dbContext);
+            string appendDir = Path.Combine(dirName, "append");
+            bool appendDirExists = LoadAppend(appendDir, dbContext);
             LoadFragments(Path.Combine(dirName, "fragments"), dbContext);
             LoadScenarios(Path.Combine(dirName, "scenarios"), dbContext);
+            if (appendDirExists) {
+                LoadClassification(appendDir, dbContext);
+            }
         }

         private static bool ImportCategorySystem(Row row, DbContextWrapper dbContext) {
@@ -532,8 +536,9 @@
         /// Load CSV files in append directory
         /// </summary>
         /// <param name="dirName">Full path name of append directory</param>
-        public static void LoadAppend(string dirName, DbContextWrapper dbContext) {
-            if (Directory.Exists(dirName)) {
+        public static bool LoadAppend(string dirName, DbContextWrapper dbContext) {
+            bool appendExists = Directory.Exists(dirName);
+            if (appendExists) {
                 IEnumerable<Row> rows;
                 Program.Logger.InfoFormat("Load append files in {0}...", dirName);
                 UpdateDataSource(DataSourceEnum.append, dirName, dbContext);
@@ -545,15 +550,24 @@
                 ImportCSV(Path.Combine(dirName, "CompositionModel.csv"), ImportCompositionModel, dbContext);
                 ImportCSV(Path.Combine(dirName, "CompositionData.csv"), ImportCompositionData, dbContext);
                 ImportCSV(Path.Combine(dirName, "ProcessComposition.csv"), ImportProcessComposition, dbContext);
-                // Import Classification last because it references UUIDs in other files
-                // Improve performance by disabling AutoDetectChanges and only executing Adds (no updates).
-                dbContext.SetAutoDetectChanges(false);
-                ImportCSV(Path.Combine(dirName, "Classification.csv"), ImportClassification, dbContext);
-                dbContext.SetAutoDetectChanges(true);
+                // Defer loading Classification until the end.
             }
             else {
                 Program.Logger.WarnFormat("Append folder, {0}, does not exist.", dirName);
             }
+            return appendExists;
+        }
+
+        /// <summary>
+        /// Import Classification last because it references UUIDs in other files and will end with large DbSet.
+        ///  Improve performance by disabling AutoDetectChanges and only executing Adds (no updates).
+        /// </summary>
+        /// <param name="dirName"></param>
+        /// <param name="dbContext"></param>
+        public static void LoadClassification(string dirName, DbContextWrapper dbContext) {
+            dbContext.SetAutoDetectChanges(false);
+            ImportCSV(Path.Combine(dirName, "Classification.csv"), ImportClassification, dbContext);
+            dbContext.SetAutoDetectChanges(true);
         }

         /// <summary>


Add preview button for main citizen model

--- Debugger/GUIExplorer/GUIButtons.cs
+++ Debugger/GUIExplorer/GUIButtons.cs
@@ -85,6 +85,13 @@
             else if (value is CitizenInfo)
             {
                 var info = (CitizenInfo)value;
+                if (info.m_skinRenderer?.sharedMesh != null)
+                {
+                    if (GUILayout.Button("Preview"))
+                    {
+                        MeshViewer.CreateMeshViewer(info.name, info.m_skinRenderer?.sharedMesh, info.m_skinRenderer?.sharedMaterial);
+                    }
+                }
                 if (info.m_lodMesh != null)
                 {
                     if (GUILayout.Button("Preview LOD"))


Avoid problems with deferred execution (seemed to be causing an error relating to multiple transactions used at the same time).

--- UserGroupPermissions/Businesslogic/UserTypePermissionsService.cs
+++ UserGroupPermissions/Businesslogic/UserTypePermissionsService.cs
@@ -61,7 +61,7 @@

             // Get the permissions for the user type.
-            var userTypePermissions = GetUserTypePermissions(userType, nodeId).ToList();
+            var userTypePermissions = GetUserTypePermissions(userType, nodeId);

             // Create a permission string.
@@ -170,7 +170,7 @@
                 NodeId = newNodeId,
                 PermissionId = x.PermissionId,
                 UserTypeId = x.UserTypeId
-            });
+            }).ToArray();
             _sqlHelper.BulkInsertRecords(items);
         }

@@ -392,7 +392,7 @@
                     .On("a.NodeId = b.nodeId AND a.PermissionId = b.permission AND b.userId = c.id")
                     .Where("a.UserTypeId = @0 AND a.NodeId IN (@1) AND b.userId IS NULL",
                         userTypeId, groupedNodeIds);
-                var rows = _sqlHelper.Query<User2NodePermissionDto>(query);
+                var rows = _sqlHelper.Query<User2NodePermissionDto>(query).ToArray();
                 _sqlHelper.BulkInsertRecords(rows);
             }
         }
@@ -430,7 +430,7 @@
                     NodeId = x.NodeId,
                     PermissionId = permissionKey.ToString(),
                     UserTypeId = userTypeId
-                });
+                }).ToArray();

                 // Bulk insert the rows.
@@ -479,7 +479,7 @@
                 .From("UserTypePermissions")
                 .Where("UserTypeId = @0 AND NodeId = @1", userType.Id, nodeId);
             var items = _sqlHelper.Fetch<UserTypePermissionRow>(query);
-            return items;
+            return items.ToArray();
         }

         #endregion


Add synchronisation events to MjScene

Add synchronisation events to MjScene

--- unity/Runtime/Components/MjScene.cs
+++ unity/Runtime/Components/MjScene.cs
@@ -76,6 +76,10 @@

   private List<MjComponent> _orderedComponents;

+  public EventHandler preUpdateEvent;
+  public EventHandler<MjStepArgs> ctrlCallback;
+  public EventHandler postUpdateEvent;
+
   protected unsafe void Start() {
     CreateScene();
   }
@@ -85,7 +89,9 @@
   }

   protected unsafe void FixedUpdate() {
+    preUpdateEvent?.Invoke(this, EventArgs.Empty);
     StepScene();
+    postUpdateEvent?.Invoke(this, EventArgs.Empty);
   }

   public bool SceneRecreationAtLateUpdateRequested = false;
@@ -314,7 +320,14 @@
     }
     Profiler.BeginSample("MjStep");
     Profiler.BeginSample("MjStep.mj_step");
-    MujocoLib.mj_step(Model, Data);
+    if (ctrlCallback != null){
+      MujocoLib.mj_step1(Model, Data);
+      ctrlCallback?.Invoke(this, new MjStepArgs(Model, Data));
+      MujocoLib.mj_step2(Model, Data);
+    }
+    else {
+      MujocoLib.mj_step(Model, Data);
+    }
     Profiler.EndSample(); // MjStep.mj_step
     CheckForPhysicsException();

@@ -447,5 +460,18 @@
       Debug.LogWarning("Failed to save Xml to a file: " + ex.ToString(), this);
     }
   }
+
+
 }
-}
+
+  public class MjStepArgs : EventArgs
+  {
+    public unsafe MjStepArgs(MujocoLib.mjModel_* model, MujocoLib.mjData_* data){
+      this.model = model;
+      this.data = data;
+    }
+    public readonly unsafe MujocoLib.mjModel_* model;
+    public readonly unsafe MujocoLib.mjData_* data;
+  }
+
+}


Add MjScene property to check if scene has initialized

--- unity/Runtime/Components/MjScene.cs
+++ unity/Runtime/Components/MjScene.cs
@@ -62,6 +62,8 @@
       return _instance;
     }
   }
+
+  public static bool InstanceExists { get => _instance != null; }

   public void Awake() {
     if (_instance == null) {


Additional error handling around script starting

--- letsencrypt-win-simple/Clients/ScriptClient.cs
+++ letsencrypt-win-simple/Clients/ScriptClient.cs
@@ -27,25 +27,35 @@
                 if (!string.IsNullOrWhiteSpace(parameterTemplate))
                 {
                     var parametersFormat = string.Format(parameterTemplate, parameters);
-                    Program.Log.Information(true, "Running {script} with {parameters}", script, parametersFormat);
+                    Program.Log.Information(true, "Script {script} starting with parameters {parameters}...", script, parametersFormat);
                     PSI.Arguments = parametersFormat;
                 }
                 else
                 {
-                    Program.Log.Information(true, "Running {script}", script);
+                    Program.Log.Information(true, "Script {script} starting...", script);
                 }
-
-                var process = new Process { StartInfo = PSI };
-                process.OutputDataReceived += (s, e) => { if (e.Data != null) Program.Log.Verbose("Script output: {0}", e.Data); };
-                process.ErrorDataReceived += (s, e) => { if (e.Data != null) Program.Log.Error("Script error: {0}", e.Data); };
-                process.Start();
-                process.BeginOutputReadLine();
-                process.BeginErrorReadLine();
-                process.WaitForExit();
-                if (process.ExitCode != 0)
+                try
                 {
-                    Program.Log.Warning("Process finished with ExitCode {code}", process.ExitCode);
+                    var process = new Process { StartInfo = PSI };
+                    process.OutputDataReceived += (s, e) => { if (e.Data != null) Program.Log.Verbose("Script output: {0}", e.Data); };
+                    process.ErrorDataReceived += (s, e) => { if (e.Data != null) Program.Log.Error("Script error: {0}", e.Data); };
+                    process.Start();
+                    process.BeginOutputReadLine();
+                    process.BeginErrorReadLine();
+                    process.WaitForExit();
+                    if (process.ExitCode != 0)
+                    {
+                        Program.Log.Warning("Script finished with ExitCode {code}", process.ExitCode);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    Program.Log.Error(ex, "Script is unable to start");
                 }
+            }
+            else
+            {
+                Program.Log.Warning("No script configured.");
             }
         }


Update ReadMeExample.cs

Update ReadMeExample.cs

--- samples/BinanceConsoleApp/Examples/ReadMeExample.cs
+++ samples/BinanceConsoleApp/Examples/ReadMeExample.cs
@@ -35,9 +35,6 @@

                 try
                 {
-                    // Validate client order.
-                    order.Validate();
-
                     // Send the TEST order.
                     await api.TestPlaceAsync(order);


Delete MainWindow.xaml.cs

Delete MainWindow.xaml.cs

[skip ci]

--- samples/Core2D.SkiaViewNoAutofac/MainWindow.xaml.cs
+++ samples/Core2D.SkiaViewNoAutofac/MainWindow.xaml.cs
@@ -1,77 +0,0 @@
-// Copyright (c) Wiesław Šoltés. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System;
-using System.Diagnostics;
-using System.Windows;
-using Microsoft.Win32;
-
-namespace Core2D.SkiaViewNoAutofac
-{
-    public partial class MainWindow : Window
-    {
-        private NoAutofacSkiaViewHelper Helper { get; set; }
-
-        public MainWindow()
-        {
-            InitializeComponent();
-            Initialize();
-        }
-
-        private void Initialize()
-        {
-            Helper = new NoAutofacSkiaViewHelper(CanvasElement);
-            Loaded += MainWindow_Loaded;
-            FileOpen.Click += FileOpen_Click;
-            FileClose.Click += FileClose_Click;
-            FileExit.Click += FileExit_Click;
-        }
-
-        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
-        {
-            CanvasElement.Focusable = true;
-            CanvasElement.Focus();
-            Helper.RefreshRequested(null, null);
-        }
-
-        private void FileOpen_Click(object sender, RoutedEventArgs e)
-        {
-            try
-            {
-                var dlg = new OpenFileDialog()
-                {
-                    Filter = "Project (*.project)|*.project|All (*.*)|*.*"
-                };
-
-                if (dlg.ShowDialog(this) == true)
-                {
-                    Helper.OpenProject(dlg.FileName);
-                    Helper.RefreshRequested(null, null);
-                }
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine(ex.Message);
-                Debug.WriteLine(ex.StackTrace);
-            }
-        }
-
-        private void FileClose_Click(object sender, RoutedEventArgs e)
-        {
-            try
-            {
-                Helper.CloseProject();
-                Helper.RefreshRequested(null, null);
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine(ex.Message);
-                Debug.WriteLine(ex.StackTrace);
-            }
-        }
-
-        private void FileExit_Click(object sender, RoutedEventArgs e)
-        {
-            Close();
-        }
-    }
-}


Fixed a performance issue with the MoveUtility

--- DotNetEngine.Engine/MoveUtility.cs
+++ DotNetEngine.Engine/MoveUtility.cs
@@ -150,21 +150,7 @@
            18085043209519168, 9042521604759584, 4521260802379792, 2260630401189896, 0, 0
         };

-        internal static ulong WhiteCastleOOMask { get { return GetBitStatesByBoardIndex(1, 6) | GetBitStatesByBoardIndex(1, 7); } }
-        internal static ulong WhiteCastleOOOMask { get { return GetBitStatesByBoardIndex(1, 2) | GetBitStatesByBoardIndex(1, 3) | GetBitStatesByBoardIndex(1, 4); } }
-        internal static ulong BlackCastleOOMask { get { return GetBitStatesByBoardIndex(8, 6) | GetBitStatesByBoardIndex(8, 7); } }
-        internal static ulong BlackCastleOOOMask { get { return GetBitStatesByBoardIndex(8, 2) | GetBitStatesByBoardIndex(8, 3) | GetBitStatesByBoardIndex(8, 4); } }
-
-        /// <summary>
-        /// Implementation of bitscanforward.
-        /// Authored by Kim Walish
-        /// </summary>
-        /// <param name="board"></param>
-        /// <see cref="http://chessprogramming.wikispaces.com/BitScan"/>
-        /// <returns>The lsb that is set on a board</returns>
-        internal static uint GetFirstPieceFromBitBoard(this ulong board)
-        {
-            var index = new uint[]
+		internal static uint[] firstPieceArray = new uint[]
             {
                 0, 47,  1, 56, 48, 27,  2, 60,
                 57, 49, 41, 37, 28, 16,  3, 61,
@@ -176,10 +162,24 @@
                 13, 18,  8, 12,  7,  6,  5, 63
             };

+        internal static ulong WhiteCastleOOMask { get { return GetBitStatesByBoardIndex(1, 6) | GetBitStatesByBoardIndex(1, 7); } }
+        internal static ulong WhiteCastleOOOMask { get { return GetBitStatesByBoardIndex(1, 2) | GetBitStatesByBoardIndex(1, 3) | GetBitStatesByBoardIndex(1, 4); } }
+        internal static ulong BlackCastleOOMask { get { return GetBitStatesByBoardIndex(8, 6) | GetBitStatesByBoardIndex(8, 7); } }
+        internal static ulong BlackCastleOOOMask { get { return GetBitStatesByBoardIndex(8, 2) | GetBitStatesByBoardIndex(8, 3) | GetBitStatesByBoardIndex(8, 4); } }
+
+        /// <summary>
+        /// Implementation of bitscanforward.
+        /// Authored by Kim Walish
+        /// </summary>
+        /// <param name="board"></param>
+        /// <see cref="http://chessprogramming.wikispaces.com/BitScan"/>
+        /// <returns>The lsb that is set on a board</returns>
+        internal static uint GetFirstPieceFromBitBoard(this ulong board)
+        {
             const ulong debruijn = 0x03f79d71b4cb0a89;
             Debug.Assert(board != 0);

-            return index[((board ^ (board - 1)) * debruijn) >> 58];
+			return firstPieceArray[((board ^ (board - 1)) * debruijn) >> 58];
         }

 		/// <summary>


Fixed issue #57.

Fixed issue #57.

git-svn-id: bf0bd98e94caaaf89d4dca54eab1bef459ce3438@162 59da171f-624f-0410-aa54-27559c288bec

--- Duplicati/Library/Main/RSyncDir.cs
+++ Duplicati/Library/Main/RSyncDir.cs
@@ -260,11 +260,10 @@
             {
                 if (m_unproccesed.Files.Count == 0)
                 {
-                    foreach (string s in m_unproccesed.FilesWithError)
-                        if (m_oldSignatures.ContainsKey(s))
-                            m_oldSignatures.Remove(s);
-
-                    m_deletedfiles.AddRange(m_oldSignatures.Keys);
+
+                    foreach(string s in m_oldSignatures.Keys)
+                        if (!m_unproccesed.IsAffectedByError(System.IO.Path.Combine(m_sourcefolder, s)))
+                            m_deletedfiles.Add(s);

                     if (m_deletedfiles.Count > 0)
                     {
@@ -863,7 +862,7 @@
                     if (path.StartsWith(s))
                         return true;

-                return false;
+                return m_filesWithError.Contains(path);
             }
         }


Added minor delays to purge unittest to avoid errors that happen when timestamps are back-to-back

--- Duplicati/UnitTest/PurgeTesting.cs
+++ Duplicati/UnitTest/PurgeTesting.cs
@@ -57,17 +57,22 @@
                 var res = c.Backup(new string[] { DATAFOLDER }, new Library.Utility.FilterExpression(round1.Select(x => "*" + Path.DirectorySeparatorChar + x)));
                 Assert.AreEqual(res.AddedFiles, round1.Length);
             }
+
+            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(3));
             using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
             {
                 var res = c.Backup(new string[] { DATAFOLDER }, new Library.Utility.FilterExpression(round2.Select(x => "*" + Path.DirectorySeparatorChar + x)));
                 Assert.AreEqual(res.AddedFiles, round2.Length - round1.Length);
             }
+
+            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(3));
             using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
             {
                 var res = c.Backup(new string[] { DATAFOLDER });
                 Assert.AreEqual(res.AddedFiles, filenames.Count - round2.Length);
             }

+            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(3));
             var last_ts = DateTime.Now;

             using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts.Expand(new { list_sets_only = true }), null))


BulkRead of not Unique Prop changes

BulkRead of not Unique Prop changes

--- EFCore.BulkExtensions/TableInfo.cs
+++ EFCore.BulkExtensions/TableInfo.cs
@@ -631,7 +631,7 @@
             foreach (var existingEntity in existingEntities)
             {
                 string uniqueProperyValues = GetUniquePropertyValues(existingEntity, selectByPropertyNames, FastPropertyDict);
-                existingEntitiesDict.Add(uniqueProperyValues, existingEntity);
+                existingEntitiesDict.TryAdd(uniqueProperyValues, existingEntity);
             }

             for (int i = 0; i < NumberOfEntities; i++)