Add GetHashCode to Option<T>

Add GetHashCode to Option<T>

--- SharpLayout/Option.cs
+++ SharpLayout/Option.cs
@@ -11,7 +11,7 @@
     /// F# https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/options-%5Bfsharp%5D
     /// C# Roslyn https://github.com/dotnet/roslyn/blob/56f605c41915317ccdb925f66974ee52282609e7/src/Compilers/Core/Portable/Optional.cs
     /// </summary>
-    public struct Option<T>
+    public struct Option<T> : IEquatable<Option<T>>
     {
         private readonly T value;
         public bool HasValue { get; }
@@ -62,6 +62,25 @@

         public Option<T> Where(Func<T, bool> predicate)
             => HasValue ? (predicate(Value) ? this : new Option<T>()) : new Option<T>();
+
+        public bool Equals(Option<T> other)
+        {
+            return EqualityComparer<T>.Default.Equals(value, other.value) && HasValue == other.HasValue;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            return obj is Option<T> option && Equals(option);
+        }
+
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                return (EqualityComparer<T>.Default.GetHashCode(value) * 397) ^ HasValue.GetHashCode();
+            }
+        }
     }

     public static class Option


Potentially fixed a bug where days other than the start day were improperly colored, and colors should now update when a task is removed.  Will need to test on a Windows machine since I coded this on Ubuntu and couldn't test.

--- Saveyour/Saveyour/WeeklyToDo.xaml.cs
+++ Saveyour/Saveyour/WeeklyToDo.xaml.cs
@@ -147,7 +147,7 @@
 	/*Recolors the given day of the week (0=Sunday ... 6 = Saturday) based upon the weights of all the tasks in that day. */
 	private void colorByWeights(int dayOfWeek){ //Currently only adds in today.
 		// Converts the int for the dayOfWeek to the date that it corrsponds to
-		DateTime day = curTopDay.AddDays(((int)(curTopDay.DayOfWeek) - dayOfWeek + 7)%7 );
+		DateTime day = curTopDay.AddDays((dayOfWeek + 7 - (int)(curTopDay.DayOfWeek) )%7 );
 		int weight = sumOfTaskWeights(day);
 		if (weight < 5){
             		borders[dayOfWeek*2].Background = new SolidColorBrush(Colors.Green); //changes background color of title
@@ -185,7 +185,7 @@
         }
         catch (KeyNotFoundException e)
         {
-
+		//No tasks for this day, weight should stay at 0.
         }
 		return sum;
 	}
@@ -307,6 +307,10 @@
             //Removes all the elements displaying the task on the WeeklyToDo GUI
             StackPanel taskStack = (StackPanel)((Button)sender).Parent;
             taskStack.Children.Clear();
+
+	    //Update the colors based upon the new list of tasks for that day.
+	    int dayOfWeek = (int)task.getDate().DayOfWeek;
+	    colorByWeights(dayOfWeek);
         }

         /* This method is called when a TaskTitle textblock is clicked! */


Fix: Remove plural form

Fix: Remove plural form

--- SharpResume/Resume.cs
+++ SharpResume/Resume.cs
@@ -7,9 +7,9 @@
 	public class Resume
 	{
 		public Basics Basics { get; set; }
-		public Work[] Works { get; set; }
-		public Volunteer[] Volunteers { get; set; }
-		public Education[] Educations { get; set; }
+		public Work[] Work { get; set; }
+		public Volunteer[] Volunteer { get; set; }
+		public Education[] Education { get; set; }
 		public Award[] Awards { get; set; }
 		public Publication[] Publications { get; set; }
 		public Skill[] Skills { get; set; }


add capacity in OrderedList

add capacity in OrderedList

--- Scripts/DapCore/util_/OrderedList.cs
+++ Scripts/DapCore/util_/OrderedList.cs
@@ -6,8 +6,18 @@

 namespace angeldnd.dap {
     public abstract class OrderedList<T, TOrder> {
-        private List<T> _Values = new List<T>();
-        private Dictionary<T, TOrder> _Orders = new Dictionary<T, TOrder>();
+        private List<T> _Values = null;
+        private Dictionary<T, TOrder> _Orders = null;
+
+        protected OrderedList(int capacity) {
+            _Values = new List<T>(capacity);
+            _Orders = new Dictionary<T, TOrder>(capacity);
+        }
+
+        protected OrderedList() {
+            _Values = new List<T>();
+            _Orders = new Dictionary<T, TOrder>();
+        }

         public int Add(T v, TOrder order) {
             if (Contains(v)) return -1;
@@ -59,24 +69,48 @@
     }

     public class IntOrderedList<T> : OrderedList<T, int> {
+        public IntOrderedList(int capacity) : base(capacity) {
+        }
+
+        public IntOrderedList() : base() {
+        }
+
         protected override int Compare(int a, int b) {
             return a.CompareTo(b);
         }
     }

     public class LongOrderedList<T> : OrderedList<T, long> {
+        public LongOrderedList(int capacity) : base(capacity) {
+        }
+
+        public LongOrderedList() : base() {
+        }
+
         protected override int Compare(long a, long b) {
             return a.CompareTo(b);
         }
     }

     public class FloatOrderedList<T> : OrderedList<T, float> {
+        public FloatOrderedList(int capacity) : base(capacity) {
+        }
+
+        public FloatOrderedList() : base() {
+        }
+
         protected override int Compare(float a, float b) {
             return a.CompareTo(b);
         }
     }

     public class DoubleOrderedList<T> : OrderedList<T, double> {
+        public DoubleOrderedList(int capacity) : base(capacity) {
+        }
+
+        public DoubleOrderedList() : base() {
+        }
+
         protected override int Compare(double a, double b) {
             return a.CompareTo(b);
         }


Updated JSConsole

Updated JSConsole

--- NiL.JS/BaseLibrary/Console.cs
+++ NiL.JS/BaseLibrary/Console.cs
@@ -192,11 +192,10 @@
             if (_lineSplitter == null)
                 _lineSplitter = new Regex("\r\n?|\n");

-            var __a = args[0];
-            if (__a == null)
+            if (args[0] == null)
                 return log(args);

-            var a = __a.Value as BaseLibrary.Array;
+            var a = args[0].Value as BaseLibrary.Array;
             if (a == null)
                 return log(args);

@@ -206,10 +205,9 @@

             HashSet<string> filter = null;
-            __a = args[1];
-            if (__a != null)
-            {
-                var f = __a.Value as BaseLibrary.Array;
+            if (args[1] != null)
+            {
+                var f = args[1].Value as BaseLibrary.Array;
                 if (f != null && (int)f.length > 0)
                 {
                     filter = new HashSet<string>();
@@ -232,12 +230,12 @@
                     continue;

                 var d = new Dictionary<string, string[]>();
-                for (var e = item.GetEnumerator(); e.MoveNext();)
+                foreach (var prop in item)
                 {
-                    if (filter != null && !filter.Contains(e.Current.Key))
+                    if (filter != null && !filter.Contains(prop.Key))
                         continue;

-                    string colName = e.Current.Key ?? "";
+                    string colName = prop.Key ?? "";

                     if (!cols.ContainsKey(colName))
                         cols.Add(colName, colName.Length);
@@ -245,7 +243,7 @@
                     int colWidth = cols[colName];
                     int colMaxWidth = System.Math.Max(cols[colName], _tableMaxColWidth);

-                    string[] splits = _lineSplitter.Split(Tools.JSValueToObjectString(e.Current.Value, 0));
+                    string[] splits = _lineSplitter.Split(Tools.JSValueToObjectString(prop.Value, 0));
                     var lines = new List<string>(splits.Length);
                     foreach (var line in splits)
                     {
@@ -267,7 +265,7 @@
                     }

                     cols[colName] = colWidth;
-                    d.Add(e.Current.Key, lines.ToArray());
+                    d.Add(prop.Key, lines.ToArray());
                 }

                 indexWidth = System.Math.Max(indexWidth, i.ToString().Length);
@@ -278,7 +276,7 @@
             if (rows.Count == 0 || cols.Count == 0)
                 return log(args);

-            List<string> colsN = new List<string>(new string[] { indexName });
+            List<string> colsN = new List<string> { indexName };
             if (filter != null)
                 colsN.AddRange(filter.Where((x) => cols.ContainsKey(x)));
             else
@@ -383,8 +381,6 @@
             {
                 if (c._parent == null) // GlobalContext
                     break;
-                if (i++ > Context.MaxConcurentContexts) // prevent infinite loops
-                    ExceptionHelper.Throw(new Error("Unable to trace back to root."));

                 Function owner = c._owner;
                 if (owner == null)
@@ -458,12 +454,12 @@

         public virtual JSValue groupCollapsed(Arguments args)
         {
-            return group(args); ;
+            return group(args);
         }

         public virtual JSValue groupEnd(Arguments args)
         {
-            if (_groups.Count == 0)
+            if (_groups.Count > 0)
                 _groups.RemoveAt(_groups.Count - 1);

             return JSValue.undefined;


More refactoring

More refactoring

--- SnakeMess/RedApple.cs
+++ SnakeMess/RedApple.cs
@@ -1,21 +1,7 @@
 namespace SnakeMess
 {
-
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool
-//     Changes to this file will be lost if the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-    /// <summary>
-    /// The red apple.
-    /// </summary>
     public class RedApple : Apple
     {
-        /// <summary>
-        /// The value.
-        /// </summary>
         private const int Value = 10;

         public RedApple(Vector position) : base(Value, position)


🍎 Excluding C# project on macOS

🍎 Excluding C# project on macOS

--- Engine.sharpmake.cs
+++ Engine.sharpmake.cs
@@ -252,7 +252,10 @@
             conf.AddProject<EntryPointGameProject>(target);
         }

-        conf.AddProject<UserSharpmakeProject>(target);
+        if(target.Platform == Platform.win64)
+        {
+            conf.AddProject<UserSharpmakeProject>(target);
+        }

         conf.AddProject<SharpGameProject>(target);
     }


Add security stamp claim for two factor client

--- src/Abp.ZeroCore/Authorization/AbpSignInManager.cs
+++ src/Abp.ZeroCore/Authorization/AbpSignInManager.cs
@@ -164,6 +164,12 @@
                 rememberBrowserIdentity.AddClaim(new Claim(AbpClaimTypes.TenantId, user.TenantId.Value.ToString()));
             }

+            if (UserManager.SupportsUserSecurityStamp)
+            {
+                var stamp = await UserManager.GetSecurityStampAsync(user);
+                rememberBrowserIdentity.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType, stamp));
+            }
+
             await Context.SignInAsync(IdentityConstants.TwoFactorRememberMeScheme,
                 new ClaimsPrincipal(rememberBrowserIdentity),
                 new Microsoft.AspNetCore.Authentication.AuthenticationProperties {IsPersistent = true});


Close DB on DBReader destruction

Close DB on DBReader destruction

--- EseView/DBReader.cs
+++ EseView/DBReader.cs
@@ -53,11 +53,26 @@
             Esent.JetOpenDatabase(m_sesid, filename, null, out m_dbid, OpenDatabaseGrbit.ReadOnly);
         }

+        ~DBReader()
+        {
+            Close();
+        }
+
         public void Close()
         {
-            Esent.JetCloseDatabase(m_sesid, m_dbid, CloseDatabaseGrbit.None);
-            m_sesid.End();
-            m_jetInstance.Close();
+            if (!m_sesid.Equals(JET_SESID.Nil))
+            {
+                if (!m_dbid.Equals(JET_DBID.Nil))
+                {
+                    Esent.JetCloseDatabase(m_sesid, m_dbid, CloseDatabaseGrbit.None);
+                }
+                m_sesid.End();
+            }
+
+            if (!m_jetInstance.Equals(JET_INSTANCE.Nil))
+            {
+                m_jetInstance.Close();
+            }
         }

         public IEnumerable<string> Tables


Added a debugging line for Xfer downloads

git-svn-id: e915c4f8b2ea2a6e63cbe989b51c0994a698cc26@2348 52acb1d6-8a22-11de-b505-999d5b087335

--- OpenMetaverse/AssetManager.cs
+++ OpenMetaverse/AssetManager.cs
@@ -1294,11 +1294,12 @@

                 if (packetNum == 0)
                 {
-                    // This is the first packet received in the download, the first four bytes are a network order size integer
-                    // FIXME: Is this actually true?
+                    // This is the first packet received in the download, the first four bytes are a size integer
                     byte[] bytes = xfer.DataPacket.Data;
                     download.Size = (bytes[3] + (bytes[2] << 8) + (bytes[1] << 16) + (bytes[0] << 24));
                     download.AssetData = new byte[download.Size];
+
+                    Logger.DebugLog("Received first packet in an Xfer download of size " + download.Size);

                     Buffer.BlockCopy(xfer.DataPacket.Data, 4, download.AssetData, 0, xfer.DataPacket.Data.Length - 4);
                     download.Transferred += xfer.DataPacket.Data.Length - 4;


Use azure hosted server for now

Use azure hosted server for now

--- src/AppGet/PackageRepository/AppGetServerClient.cs
+++ src/AppGet/PackageRepository/AppGetServerClient.cs
@@ -11,7 +11,7 @@
         private readonly Logger _logger;
         private readonly HttpRequestBuilder _requestBuilder;

-        private const string API_ROOT = "https://appget.net/api/v1/";
+        private const string API_ROOT = "https://appget.azurewebsites.net/v1/";

         public AppGetServerClient(IHttpClient httpClient, Logger logger)
         {


Update document object with convert method.

--- src/Arango/Arango.Client/API/Documents/Document.cs
+++ src/Arango/Arango.Client/API/Documents/Document.cs
@@ -35,7 +35,7 @@
             }
             else
             {
-                return Convert.ToBoolean(fieldValue);
+                return System.Convert.ToBoolean(fieldValue);
             }
         }

@@ -49,7 +49,7 @@
             }
             else
             {
-                return Convert.ToByte(fieldValue);
+                return System.Convert.ToByte(fieldValue);
             }
         }

@@ -63,7 +63,7 @@
             }
             else
             {
-                return Convert.ToInt16(fieldValue);
+                return System.Convert.ToInt16(fieldValue);
             }
         }

@@ -77,7 +77,7 @@
             }
             else
             {
-                return Convert.ToInt32(fieldValue);
+                return System.Convert.ToInt32(fieldValue);
             }
         }

@@ -91,7 +91,7 @@
             }
             else
             {
-                return Convert.ToInt64(fieldValue);
+                return System.Convert.ToInt64(fieldValue);
             }
         }

@@ -105,7 +105,7 @@
             }
             else
             {
-                return Convert.ToSingle(fieldValue);
+                return System.Convert.ToSingle(fieldValue);
             }
         }

@@ -119,7 +119,7 @@
             }
             else
             {
-                return Convert.ToDouble(fieldValue);
+                return System.Convert.ToDouble(fieldValue);
             }
         }

@@ -133,7 +133,7 @@
             }
             else
             {
-                return Convert.ToDecimal(fieldValue);
+                return System.Convert.ToDecimal(fieldValue);
             }
         }

@@ -197,34 +197,34 @@
                 switch (type.Name)
                 {
                     case "Boolean":
-                        collection = ((List<object>)data).Select(Convert.ToBoolean).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToBoolean).ToList() as List<T>;
                         break;
                     case "Byte":
-                        collection = ((List<object>)data).Select(Convert.ToByte).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToByte).ToList() as List<T>;
                         break;
                     case "Int16":
-                        collection = ((List<object>)data).Select(Convert.ToInt16).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToInt16).ToList() as List<T>;
                         break;
                     case "Int32":
-                        collection = ((List<object>)data).Select(Convert.ToInt32).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToInt32).ToList() as List<T>;
                         break;
                     case "Int64":
-                        collection = ((List<object>)data).Select(Convert.ToInt64).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToInt64).ToList() as List<T>;
                         break;
                     case "Single":
-                        collection = ((List<object>)data).Select(Convert.ToSingle).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToSingle).ToList() as List<T>;
                         break;
                     case "Double":
-                        collection = ((List<object>)data).Select(Convert.ToDouble).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToDouble).ToList() as List<T>;
                         break;
                     case "Decimal":
-                        collection = ((List<object>)data).Select(Convert.ToDecimal).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToDecimal).ToList() as List<T>;
                         break;
                     case "DateTime":
-                        collection = ((List<object>)data).Select(Convert.ToDateTime).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToDateTime).ToList() as List<T>;
                         break;
                     case "String":
-                        collection = ((List<object>)data).Select(Convert.ToString).ToList() as List<T>;
+                        collection = ((List<object>)data).Select(System.Convert.ToString).ToList() as List<T>;
                         break;
                     default:
                         collection = ((IEnumerable)data).Cast<T>().ToList();
@@ -788,6 +788,101 @@

         #endregion

+        #region Field type conversion
+
+        public Document Convert(string fieldPath, Type type)
+        {
+            var currentField = "";
+            var arrayContent = "";
+
+            if (fieldPath.Contains("."))
+            {
+                var fields = fieldPath.Split('.');
+                var iteration = 1;
+                var embeddedDocument = this;
+
+                foreach (var field in fields)
+                {
+                    currentField = field;
+                    arrayContent = "";
+
+                    if (field.Contains("["))
+                    {
+                        var firstIndex = field.IndexOf('[');
+                        var lastIndex = field.IndexOf(']');
+
+                        arrayContent = field.Substring(firstIndex + 1, lastIndex - firstIndex - 1);
+                        currentField = field.Substring(0, firstIndex);
+                    }
+
+                    if (iteration == fields.Length)
+                    {
+                        if (embeddedDocument.ContainsKey(currentField))
+                        {
+                            embeddedDocument[currentField] = ConvertField(embeddedDocument[currentField], type);
+                        }
+
+                        break;
+                    }
+
+                    if (embeddedDocument.ContainsKey(currentField))
+                    {
+                        embeddedDocument = (Document)GetFieldValue(currentField, arrayContent, embeddedDocument);
+                    }
+                    else
+                    {
+                        // if current field in path isn't present
+                        break;
+                    }
+
+                    iteration++;
+                }
+            }
+            else
+            {
+                currentField = fieldPath;
+
+                if (fieldPath.Contains("["))
+                {
+                    var firstIndex = fieldPath.IndexOf('[');
+                    var lastIndex = fieldPath.IndexOf(']');
+
+                    arrayContent = fieldPath.Substring(firstIndex + 1, lastIndex - firstIndex - 1);
+                    currentField = fieldPath.Substring(0, firstIndex);
+                }
+
+                if (this.ContainsKey(currentField))
+                {
+                    this[currentField] = ConvertField(this[currentField], type);
+                }
+            }
+
+            return this;
+        }
+
+        private object ConvertField(object value, Type type, DateTimeFormat dateTimeFormat = DateTimeFormat.DateTimeObject)
+        {
+            var valueType = value.GetType();
+
+            if ((valueType.Name == "DateTime") && (type.Name == "String"))
+            {
+                value = ((DateTime)value).ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", DateTimeFormatInfo.InvariantInfo);
+            }
+            else if ((valueType.Name == "DateTime") && (type.Name == "Int64"))
+            {
+                TimeSpan span = (((DateTime)value).ToUniversalTime() - DocumentSettings.UnixEpoch);
+                value = (long)span.TotalSeconds;
+            }
+            else
+            {
+                value = System.Convert.ChangeType(value, type);
+            }
+
+            return value;
+        }
+
+        #endregion
+
         public Document Drop(string fieldPath)
         {
             var currentField = "";
@@ -1202,7 +1297,7 @@
                         }
                         else
                         {
-                            propertyInfo.SetValue(genericObject, Convert.ChangeType(fieldValue, propertyInfo.PropertyType), null);
+                            propertyInfo.SetValue(genericObject, System.Convert.ChangeType(fieldValue, propertyInfo.PropertyType), null);
                         }
                     }
                 }
@@ -1263,7 +1358,7 @@
                                 }
                                 else
                                 {
-                                    ((IList)collectionObject).Add(Convert.ChangeType(collection[i], collectionType));
+                                    ((IList)collectionObject).Add(System.Convert.ChangeType(collection[i], collectionType));
                                 }
                             }
                         }
@@ -1454,34 +1549,34 @@
                 switch (type.Name)
                 {
                     case "Boolean":
-                        collection = data.Select(Convert.ToBoolean).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToBoolean).ToList() as List<T>;
                         break;
                     case "Byte":
-                        collection = data.Select(Convert.ToByte).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToByte).ToList() as List<T>;
                         break;
                     case "Int16":
-                        collection = data.Select(Convert.ToInt16).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToInt16).ToList() as List<T>;
                         break;
                     case "Int32":
-                        collection = data.Select(Convert.ToInt32).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToInt32).ToList() as List<T>;
                         break;
                     case "Int64":
-                        collection = data.Select(Convert.ToInt64).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToInt64).ToList() as List<T>;
                         break;
                     case "Single":
-                        collection = data.Select(Convert.ToSingle).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToSingle).ToList() as List<T>;
                         break;
                     case "Double":
-                        collection = data.Select(Convert.ToDouble).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToDouble).ToList() as List<T>;
                         break;
                     case "Decimal":
-                        collection = data.Select(Convert.ToDecimal).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToDecimal).ToList() as List<T>;
                         break;
                     case "DateTime":
-                        collection = data.Select(Convert.ToDateTime).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToDateTime).ToList() as List<T>;
                         break;
                     case "String":
-                        collection = data.Select(Convert.ToString).ToList() as List<T>;
+                        collection = data.Select(System.Convert.ToString).ToList() as List<T>;
                         break;
                     default:
                         collection = ((IEnumerable)data).Cast<T>().ToList();


#21 #22 IFileStore

#21 #22 IFileStore

--- src/AutoClicker/Model/ExecutableSteps/ClickStep.cs
+++ src/AutoClicker/Model/ExecutableSteps/ClickStep.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Drawing;
+using System.IO;
 using AutoClicker.Model.Abstraction;
 using AutoClicker.Model.Abstraction.Interface;
 using AutoClicker.Model.Abstraction.Interface.Inputs;
@@ -11,23 +12,28 @@
     {
         private readonly ISearchPictureModule _searchPicture;
         private readonly IMouseEventModule _clickModule;
+        private readonly IFileStore _fileStore;
         private readonly string _name;
         private MouseEventType _type;
         private readonly uint _count;
-        public ClickStep(string id, MouseEventType type, uint count, ISearchPictureModule searchPictureModule, string name) : base(id)
+        public ClickStep(string id, MouseEventType type, uint count, ISearchPictureModule searchPictureModule, IFileStore fileStore, string name) : base(id)
         {
             _name = name;
             _searchPicture = searchPictureModule;
             _clickModule = new MouseEventModule();
             _type = type;
             _count = count;
+            _fileStore = fileStore;
         }

         public override AggregateException GetValidateException()
         {
             var exeptions = new List<Exception>();

-            //TODO : Kos add exeption if file don't exist
+            if (!_fileStore.FileExist(_name))
+            {
+                exeptions.Add(new FileNotFoundException(_name));
+            }
             var childEx = base.GetValidateException();

             exeptions.AddRange(childEx.InnerExceptions);


ProcessMethodInvocation should be overridable

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@2272 2c1201b4-01cd-e047-a400-b836ae1fbc61

--- src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
+++ src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
@@ -3821,7 +3821,7 @@
 			}
 		}

-		private void ProcessMethodInvocation(MethodInvocationExpression node, IEntity targetEntity)
+		protected virtual void ProcessMethodInvocation(MethodInvocationExpression node, IEntity targetEntity)
 		{
 			IMethod targetMethod = (IMethod)targetEntity;
 			if (!CheckParameters(targetMethod.CallableType, node.Arguments, false))


refactor: support Date timestamp in v5 breadcrumbs

--- src/BugsnagUnity/Native/Android/NativeInterface.cs
+++ src/BugsnagUnity/Native/Android/NativeInterface.cs
@@ -533,17 +533,22 @@
       string typeName = AndroidJNI.CallStringMethod(type, ObjectToString, new jvalue[]{});
       AndroidJNI.DeleteLocalRef(type);

-      string name = "<empty>";
-      IntPtr nameObj = AndroidJNI.CallObjectMethod(javaBreadcrumb, BreadcrumbGetMessage, new jvalue[]{});
-      if (nameObj != IntPtr.Zero)
-      {
-        name = AndroidJNI.GetStringUTFChars(nameObj);
-      }
-      AndroidJNI.DeleteLocalRef(nameObj);
-
-      string timestamp = AndroidJNI.CallStringMethod(javaBreadcrumb, BreadcrumbGetTimestamp, new jvalue[]{});
-
-      return new Breadcrumb(name, timestamp, typeName, metadata);
+      string message = "<empty>";
+      IntPtr messageObj = AndroidJNI.CallObjectMethod(javaBreadcrumb, BreadcrumbGetMessage, new jvalue[]{});
+      if (messageObj != IntPtr.Zero)
+      {
+        message = AndroidJNI.GetStringUTFChars(messageObj);
+      }
+      AndroidJNI.DeleteLocalRef(messageObj);
+
+      IntPtr date = AndroidJNI.CallObjectMethod(javaBreadcrumb, BreadcrumbGetTimestamp, new jvalue[]{});
+      object[] args = new object[] {date};
+      jvalue[] jargs = AndroidJNIHelper.CreateJNIArgArray(args);
+      string timestamp = AndroidJNI.CallStaticStringMethod(BugsnagNativeInterface, DateToString, jargs);
+      AndroidJNIHelper.DeleteJNIArgArray(args, jargs);
+      AndroidJNI.DeleteLocalRef(date);
+
+      return new Breadcrumb(message, timestamp, typeName, metadata);
     }

     private AndroidJavaObject BuildJavaMapDisposable(IDictionary<string, string> src) {


Code optimization.

Code optimization.

--- src/Chloe/Query/Visitors/GroupKeySelectorParser.cs
+++ src/Chloe/Query/Visitors/GroupKeySelectorParser.cs
@@ -9,7 +9,7 @@

 namespace Chloe.Query.Visitors
 {
-    class GroupKeySelectorParser : ExpressionVisitor<List<DbExpression>>
+    class GroupKeySelectorParser : ExpressionVisitor<DbExpression[]>
     {
         ScopeParameterDictionary _scopeParameters;
         KeyDictionary<string> _scopeTables;
@@ -19,12 +19,12 @@
             this._scopeTables = scopeTables;
         }

-        public static List<DbExpression> Parse(Expression keySelector, ScopeParameterDictionary scopeParameters, KeyDictionary<string> scopeTables)
+        public static DbExpression[] Parse(Expression keySelector, ScopeParameterDictionary scopeParameters, KeyDictionary<string> scopeTables)
         {
             return new GroupKeySelectorParser(scopeParameters, scopeTables).Visit(keySelector);
         }

-        public override List<DbExpression> Visit(Expression exp)
+        public override DbExpression[] Visit(Expression exp)
         {
             switch (exp.NodeType)
             {
@@ -35,18 +35,18 @@
                 default:
                     {
                         var dbExp = GeneralExpressionParser.Parse(exp, this._scopeParameters, this._scopeTables);
-                        return new List<DbExpression>(1) { dbExp };
+                        return new DbExpression[1] { dbExp };
                     }
             }
         }

-        protected override List<DbExpression> VisitNew(NewExpression exp)
+        protected override DbExpression[] VisitNew(NewExpression exp)
         {
-            List<DbExpression> ret = new List<DbExpression>(exp.Arguments.Count);
+            DbExpression[] ret = new DbExpression[exp.Arguments.Count];
             for (int i = 0; i < exp.Arguments.Count; i++)
             {
                 var dbExp = GeneralExpressionParser.Parse(exp.Arguments[i], this._scopeParameters, this._scopeTables);
-                ret.Add(dbExp);
+                ret[i] = dbExp;
             }

             return ret;


Added a Control property and much documentation to the Character class.

--- Whisper.Game/Characters/Character.cs
+++ Whisper.Game/Characters/Character.cs
@@ -32,6 +32,13 @@

         private readonly ILog log = LogManager.GetLogger(typeof(Character));

+        /// <summary>
+        /// Creates a new instance of the Character class.
+        /// </summary>
+        /// <param name="id">object ID of this Character</param>
+        /// <param name="name">this Character's name</param>
+        /// <param name="actionButtons">a list of ActionButton objects for this Character</param>
+        /// <param name="spells">a list of Spells known to this Character</param>
         public Character(ObjectID id, string name, IList<ActionButton> actionButtons, IList<Spell> spells) : base(id, ObjectTypeID.Player, (ushort)CharacterFields.END)
         {
             ActionButtons = actionButtons;
@@ -40,42 +47,75 @@
             FirstLogin = false;
         }

+        /// <summary>
+        /// Gets the name of the Character.
+        /// </summary>
         public string Name
         {
             get;
             private set;
         }

+        /// <summary>
+        /// Gets or sets the current Zone ID of the Character.
+        /// </summary>
         public int ZoneID
         {
             get;
             set;
         }

+        /// <summary>
+        /// Gets or sets the bind point for this Character.
+        /// </summary>
         public OrientedVector3 BindPoint
         {
             get;
             set;
         }

+        /// <summary>
+        /// Gets a list of this Character's ActionButtons.
+        /// </summary>
         public IList<ActionButton> ActionButtons
         {
             get;
             private set;
         }

+        /// <summary>
+        /// Gets a list of Spells known to this Character.
+        /// </summary>
         public IList<Spell> Spells
         {
             get;
             private set;
         }

+        /// <summary>
+        /// Gets or sets whether this is the first time this Character has logged into the Shard.
+        /// </summary>
         public bool FirstLogin
         {
             get;
             set;
         }

+        /// <summary>
+        /// Gets the unit that this Character is controlling. This is typically the same instance as the Character itself.
+        /// </summary>
+        public Unit Control
+        {
+            get
+            {
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Initializes this Character before it is added to the Shard for the first time.
+        /// </summary>
+        /// <param name="world">static world store</param>
         public override void Initialize(World.World world)
         {
             base.Initialize(world);
@@ -125,6 +165,10 @@
             Spirit = cbs.Spirit;
         }

+        /// <summary>
+        /// Returns the name of this Character.
+        /// </summary>
+        /// <returns>the name of this Character</returns>
         public override string ToString()
         {
             return Name;


멀티스레드지만 UI쓰레드 여전히 묶여있음.

멀티스레드지만 UI쓰레드 여전히 묶여있음.

--- WpfHealthBreezeTV/MainWindow.xaml.cs
+++ WpfHealthBreezeTV/MainWindow.xaml.cs
@@ -44,7 +44,7 @@
             getChannelFromReg();
             initData();
             getVideos();
-            //loadImage();
+            loadImage();
             refreshMyChannel();
             refreshSearchResult();
             getPlayerSize();
@@ -89,19 +89,21 @@

         private void loadImage()
         {
-            try
-            {
-                foreach (KeyValuePair<string, Video> v in videos)
-                {
-                    v.Value.img = new BitmapImage(new Uri(v.Value.thumbnail));
-                    setImage(v.Value);
-                }
-            }
-            catch (Exception ex)
-            {
-                string error = ex.Source + "\n" + ex.Message + "\n" + ex.StackTrace;
-                MessageBox.Show(error);
-            }
+            Dispatcher uiDispatcher = Dispatcher.CurrentDispatcher;
+            BackgroundWorker worker = new BackgroundWorker();
+            worker.DoWork += (sender, e) =>
+            {
+                uiDispatcher.BeginInvoke(new Action(() =>
+                {
+                    foreach (KeyValuePair<string, Video> v in videos)
+                    {
+                        v.Value.img = new BitmapImage(new Uri(v.Value.thumbnail));
+                        setImage(v.Value);
+                    }
+                }));
+            };
+
+            worker.RunWorkerAsync();
         }

         private void setImage(Video v)
@@ -113,6 +115,7 @@
             }
         }

+        /*
         private void setImage()
         {
             foreach (KeyValuePair<string, Video> v in videos)
@@ -124,7 +127,7 @@
                 }
             }
         }
-
+        */

         /*
         private void setImage(Video v, BitmapImage img)
@@ -415,16 +418,16 @@
             Separator separator = new Separator();

             Image thumbnail = new Image();
-
-            //BitmapImage bitmapImage = new BitmapImage();
-            //bitmapImage.BeginInit();
-            //bitmapImage.UriSource = new Uri(v.thumbnail, UriKind.Relative);
-            //bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
-            //bitmapImage.EndInit();
-
-            thumbnail.Source = new BitmapImage(new Uri(v.thumbnail));
-
-            //thumbnail.Source = (v.img == null) ? new BitmapImage(new Uri("img/thumbnail.png", UriKind.Relative)) : v.img;
+            /*
+            BitmapImage bitmapImage = new BitmapImage();
+            bitmapImage.BeginInit();
+            bitmapImage.UriSource = new Uri(v.thumbnail, UriKind.Relative);
+            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
+            bitmapImage.EndInit();
+
+            //thumbnail.Source = new BitmapImage(new Uri(v.thumbnail));
+            */
+            thumbnail.Source = (v.img == null) ? new BitmapImage(new Uri("img/thumbnail.png", UriKind.Relative)) : v.img;
             //thumbnail.Source = v.img;
             thumbnail.Stretch = Stretch.Fill;
             Grid.SetRowSpan(thumbnail, 2);


Formatting changes.

Formatting changes.

--- src/Generator/Passes/GetterSetterToPropertyPass.cs
+++ src/Generator/Passes/GetterSetterToPropertyPass.cs
@@ -54,7 +54,8 @@

             if (prop == null && prop2 != null)
                 Driver.Diagnostics.EmitWarning(DiagnosticId.PropertySynthetized,
-                    "Property {0}::{1} already exist with type {2}", @class.Name, name, type.Type.ToString());
+                    "Property {0}::{1} already exist with type {2}",
+                    @class.Name, name, type.Type.ToString());

             if (prop != null)
                 return prop;
@@ -131,7 +132,8 @@

             var type = method.Parameters[0].Type;

-            var getter = @class.Methods.FirstOrDefault(m => m.Name == "Get" + name && m.Type.Equals(type));
+            var getter = @class.Methods.FirstOrDefault(m => m.Name == "Get" + name
+                && m.Type.Equals(type));

             var otherSetter = @class.Methods.FirstOrDefault(m => m.Name == method.Name
                 && m.Parameters.Count == 1


Refactored timer library Optimized timer dispatch greatly Improved timer exception message Decreased timer precision to 25ms Added basic clock skew timer recovery

--- Oxide.Core/Libraries/Timer.cs
+++ Oxide.Core/Libraries/Timer.cs
@@ -1,6 +1,7 @@
 using System;
+using System.Linq;
+using System.Collections.Generic;
 using System.Diagnostics;
-using System.Collections.Generic;

 using Oxide.Core.Plugins;

@@ -11,8 +12,6 @@
     /// </summary>
     public class Timer : Library
     {
-        #region Time Control
-
         private static Stopwatch stopwatch;

         private static float CurrentTime { get { return (float)stopwatch.Elapsed.TotalSeconds; } }
@@ -23,8 +22,6 @@
             stopwatch.Start();
         }

-        #endregion
-
         /// <summary>
         /// Represents a single timer instance
         /// </summary>
@@ -56,10 +53,10 @@
             public Plugin Owner { get; private set; }

             // The next rep time
-            private float nextrep;
-
-            /// <summary>
-            /// Initializes a new instance of the TimerInstance class
+            internal float nextrep;
+
+            /// <summary>
+            /// Initialises a new instance of the TimerInstance class
             /// </summary>
             /// <param name="repetitions"></param>
             /// <param name="delay"></param>
@@ -97,51 +94,81 @@
             /// </summary>
             public void Update()
             {
-                // Check if we need to rep
-                float ctime = CurrentTime;
-                if (ctime >= nextrep)
-                {
-                    nextrep += Delay;
-                    try
-                    {
-                        Callback();
-                    }
-                    catch (Exception ex)
-                    {
-                        Destroy();
-                        if (Owner != null)
-                            Interface.GetMod().RootLogger.WriteException(string.Format("Failed to run a timer from {0}.", Owner.Name), ex);
-                        else
-                            Interface.GetMod().RootLogger.WriteException("Failed to run a timer.", ex);
-                    }
-
-                    if (Repetitions > 0)
-                    {
-                        Repetitions--;
-                        if (Repetitions == 0) Destroy();
-                    }
+                nextrep += Delay;
+
+                try
+                {
+                    Callback();
                 }
-            }
-        }
-
-        /// <summary>
-        /// Returns if this library should be loaded into the global namespace
-        /// </summary>
+                catch (Exception ex)
+                {
+                    Destroy();
+                    Interface.GetMod().RootLogger.WriteException(Owner ? $"Failed to run a {Delay:0.00} timer in {Owner.Name}" : $"Failed to run a {Delay:0.00} timer", ex);
+                }
+
+                if (Repetitions > 0)
+                {
+                    Repetitions--;
+                    if (Repetitions == 0) Destroy();
+                }
+            }
+        }
+
         public override bool IsGlobal { get { return false; } }
-
-        private readonly HashSet<TimerInstance> alltimers;
-
-        public Timer()
-        {
-            alltimers = new HashSet<TimerInstance>();
-        }
-
-        /// <summary>
-        /// Updates all timers
+
+        private const float updateInterval = .025f;
+        private float lastUpdateAt;
+
+        private readonly List<TimerInstance> timers = new List<TimerInstance>();
+
+        /// <summary>
+        /// Updates all timers - called every server frame
         /// </summary>
         public void Update()
         {
-            alltimers.RemoveWhere(timer => { timer.Update(); return timer.Destroyed; });
+            if (timers.Count < 1) return;
+
+            var now = CurrentTime;
+
+            if (now < lastUpdateAt)
+            {
+                var difference = lastUpdateAt - now;
+                Interface.GetMod().RootLogger.Write(Logging.LogType.Warning, $"Time travelling detected! Timers were updated {difference:0.00} seconds in the future? We will attempt to recover but this should really never happen!");
+                foreach (var timer in timers) timer.nextrep -= difference;
+            }
+
+            if (now < lastUpdateAt + updateInterval) return;
+
+            var expired = timers.TakeWhile(t => t.nextrep <= now).ToArray();
+            if (expired.Length > 0)
+            {
+                timers.RemoveRange(0, expired.Length);
+                foreach (var timer in expired)
+                {
+                    timer.Update();
+                    // Add the timer back to the queue if it needs to fire again
+                    if (!timer.Destroyed) InsertTimer(timer);
+                }
+            }
+        }
+
+        private TimerInstance AddTimer(int repetitions, float delay, Action callback, Plugin owner = null)
+        {
+            var timer = new TimerInstance(repetitions, delay, callback, owner);
+            InsertTimer(timer);
+            return timer;
+        }
+
+        private void InsertTimer(TimerInstance timer)
+        {
+            var index = timers.Count;
+            for (var i = 0; i < timers.Count; i++)
+            {
+                if (timers[i].nextrep <= timer.nextrep) continue;
+                index = i;
+                break;
+            }
+            timers.Insert(index, timer);
         }

         /// <summary>
@@ -154,9 +181,7 @@
         [LibraryFunction("Once")]
         public TimerInstance Once(float delay, Action callback, Plugin owner = null)
         {
-            TimerInstance timer = new TimerInstance(1, delay, callback, owner);
-            alltimers.Add(timer);
-            return timer;
+            return AddTimer(1, delay, callback, owner);
         }

         /// <summary>
@@ -170,9 +195,7 @@
         [LibraryFunction("Repeat")]
         public TimerInstance Repeat(float delay, int reps, Action callback, Plugin owner = null)
         {
-            TimerInstance timer = new TimerInstance(reps, delay, callback, owner);
-            alltimers.Add(timer);
-            return timer;
+            return AddTimer(reps, delay, callback, owner);
         }

         /// <summary>
@@ -183,9 +206,7 @@
         [LibraryFunction("NextFrame")]
         public TimerInstance NextFrame(Action callback)
         {
-            TimerInstance timer = new TimerInstance(1, 0.0f, callback, null);
-            alltimers.Add(timer);
-            return timer;
+            return AddTimer(1, 0.0f, callback, null);
         }
     }
 }


[Modify] Edit it

[Modify] Edit it

--- Example3/Program.cs
+++ Example3/Program.cs
@@ -15,8 +15,8 @@
       // Create a new instance of the HttpServer class.
       //
       // If you would like to provide the secure connection, you should
-      // create a new instance with the 'secure' parameter set to true,
-      // or an https scheme HTTP URL.
+      // create a new instance with the 'secure' parameter set to true or
+      // with an https scheme HTTP URL.

       var httpsv = new HttpServer (4649);
       //var httpsv = new HttpServer (5963, true);


adjust shadow offset for left menu to match right menu

--- Xamarin-Sidebar/SidebarController.cs
+++ Xamarin-Sidebar/SidebarController.cs
@@ -462,7 +462,7 @@
 				return;

 			// don't add an offset if the menu is on the left
-			var xOffset = (MenuLocation == MenuLocations.Left) ? 0 : 5;
+			var xOffset = (MenuLocation == MenuLocations.Left) ? -5 : 5;

 			_contentAreaView.Layer.ShadowOffset = new SizeF(xOffset, 0);
 			_contentAreaView.Layer.ShadowPath = UIBezierPath.FromRect (_contentAreaView.Bounds).CGPath;
@@ -481,7 +481,7 @@
 				return;

 			// don't add an offset if the menu is on the left
-			position = (MenuLocation == MenuLocations.Left) ? 0 : position;
+			position = (MenuLocation == MenuLocations.Left) ? -position : position;

 			_contentAreaView.Layer.ShadowOffset = new SizeF(position, 0);
 			_contentAreaView.Layer.ShadowPath = UIBezierPath.FromRect (_contentAreaView.Bounds).CGPath;


fixed lots of NullReferenceExceptions being logged

--- FindYourShit/Mod.cs
+++ FindYourShit/Mod.cs
@@ -43,7 +43,11 @@
     {
         public override void OnUpdate()
         {
-            SearchForSomeoneRandomPanel panel = FindIt.panel.GetComponent<SearchForSomeoneRandomPanel>();
+            var go = FindIt.panel;
+            if (go == null)
+                return;
+
+            SearchForSomeoneRandomPanel panel = go.GetComponent<SearchForSomeoneRandomPanel>();
             if (panel == null)
                 return;


export key pair

export key pair

--- SshKeys/KeyPairRSA.cs
+++ SshKeys/KeyPairRSA.cs
@@ -38,6 +38,7 @@
         {
             var rsa = new RSACryptoServiceProvider(keysize);
             _keyparams = rsa.ExportParameters(true);
+            var x = rsa.ToXmlString(true);
             Passphrase = string.IsNullOrEmpty(passphrase) ? null : Encoding.Default.GetBytes(passphrase);
         }


Added test that entry contains string content

--- Tests/MetricsTests.cs
+++ Tests/MetricsTests.cs
@@ -36,7 +36,7 @@
         {
             Init();

-            var name = "TestEntry";
+            const string name = "TestEntry";

             string emittedEntryName = String.Empty;

@@ -55,7 +55,22 @@
         [Fact]
         public void entry_with_string_contains_string()
         {
-            throw new NotImplementedException();
+            Init();
+
+            const string content = "Test content";
+
+            string emittedContent = String.Empty;
+
+            mockMetricsEmitter
+                .Setup(m => m.Emit(It.IsAny<Dictionary<string, string>>(), It.IsAny<IMetric[]>()))
+                .Callback<Dictionary<string, string>, IMetric[]>((properties, metrics) => {
+                    var entry = (Metric<string>) metrics[0];
+                    emittedContent = entry.Content;
+                });
+
+            testObject.Entry("TestEntry", content);
+
+            Assert.Equal(content, emittedContent);
         }

         [Fact]


Fixed a broken test.

Fixed a broken test.

--- Tests/PromiseTests.cs
+++ Tests/PromiseTests.cs
@@ -596,8 +596,6 @@
                 .Then<IPromise<string>>(v =>
                 {
                     throw ex;
-
-                    return Promise.Resolved(string.Empty);
                 })
                 .Catch(e =>
                 {


debugging

debugging

--- Tests/TestSettings.cs
+++ Tests/TestSettings.cs
@@ -77,7 +77,13 @@
 			Console.WriteLine(settings.ServiceRootUrl);
 			Console.WriteLine(settings.ServiceRootFolder);
 			Console.WriteLine(settings.DataFolder);
-			Console.WriteLine(settings.UserName);
+			var buf = new StringBuilder();
+			foreach (var ch in settings.UserName)
+			{
+				buf.Append(ch);
+				buf.Append(' ');
+			}
+			Console.WriteLine(buf.ToString());
 			Console.WriteLine("######");

 			return settings;


Update reference to tinymce cdn

Update reference to tinymce cdn

--- AllReadyApp/Web-App/AllReady/Views/Shared/_Layout.cshtml
+++ AllReadyApp/Web-App/AllReady/Views/Shared/_Layout.cshtml
@@ -111,7 +111,7 @@
                 asp-fallback-src="~/lib/bootstrap-touch-carousel/dist/js/bootstrap-touch-carousel.js"
                 asp-fallback-test="window.Hammer && window.Hammer.Instance">
         </script>
-        <script src="//tinymce.cachefly.net/4.2.6/tinymce.min.js"
+        <script src="//cdn.tinymce.com/4/tinymce.min.js"
                 asp-fallback-src="~/lib/tinymce/tinymce.js">
         </script>
         <script src="//d3js.org/d3.v3.min.js"


Migrated the Messenger to use weak delegates.

--- ThinMvvm/Messenger.cs
+++ ThinMvvm/Messenger.cs
@@ -16,7 +16,7 @@
     /// </remarks>
     public static class Messenger
     {
-        private static readonly List<object> _handlers = new List<object>();
+        private static readonly List<Handler> _handlers = new List<Handler>();

         /// <summary>
         /// Registers the specified handler for the specified message type.
@@ -30,7 +30,7 @@
                 throw new ArgumentNullException( "handler" );
             }

-            _handlers.Add( new Handler<T>( handler ) );
+            _handlers.Add( Handler.Create( handler ) );
         }

         /// <summary>
@@ -40,7 +40,7 @@
         /// <param name="message">The message.</param>
         public static void Send<T>( T message )
         {
-            foreach ( var deadHandler in _handlers.OfType<Handler<T>>().Where( h => !h.TryHandle( message ) ).ToArray() )
+            foreach ( var deadHandler in _handlers.Where( h => !h.TryHandle( message, typeof( T ) ) ).ToArray() )
             {
                 _handlers.Remove( deadHandler );
             }
@@ -57,32 +57,48 @@

         /// <summary>
-        /// Stores data necessary to handle messages.
+        /// Handle messages (or refuses to do so).
         /// </summary>
-        /// <typeparam name="T">The message type.</typeparam>
-        private sealed class Handler<T>
+        private sealed class Handler
         {
             private readonly WeakDelegate _action;
+            private readonly Type _messageType;

             /// <summary>
-            /// Initializes a new instance of the <see cref="Handler{T}" /> class with the specified handler action.
+            /// Initializes a new instance of the <see cref="Handler" /> class with the specified action and message type.
             /// </summary>
-            /// <param name="handler">The handler.</param>
-            public Handler( Action<T> action )
+            private Handler( WeakDelegate action, Type messageType )
             {
-                _action = new WeakDelegate( action );
+                _action = action;
+                _messageType = messageType;
+            }
+
+            /// <summary>
+            /// Creates a new <see cref="Handler" /> with the specified action.
+            /// </summary>
+            /// <param name="action">The action.</param>
+            public static Handler Create<T>( Action<T> action )
+            {
+                return new Handler( new WeakDelegate( action ), typeof( T ) );
             }

             /// <summary>
-            /// Attempts to handle the specified message.
+            /// Handles the specified message if it is of the correct type.
+            /// Otherwise, does nothing.
             /// </summary>
             /// <param name="message">The message.</param>
+            /// <param name="messageType">The message type. (required because message can be null)</param>
             /// <returns>True if the handler is still alive, false otherwise.</returns>
-            public bool TryHandle( T message )
+            public bool TryHandle( object message, Type messageType )
             {
+                if ( messageType != _messageType )
+                {
+                    return true;
+                }
+
                 object ignored;
-                return _action.TryInvoke( new object[] { message }, out ignored );
+                return _action.TryInvoke( new[] { message }, out ignored );
             }
         }
     }


Updates SimpleJSON to a newer version

Updates SimpleJSON to a newer version

--- Tracker/SimpleJSON.cs
+++ Tracker/SimpleJSON.cs
@@ -19,7 +19,6 @@
 #if !UNITY_WEBPLAYER
 #define USE_FileIO
 #endif
-
 /* * * * *
  * A simple JSON Parser / builder
  * ------------------------------
@@ -34,6 +33,8 @@
  * Written by Bunny83
  * 2012-06-09
  *
+ * Modified by oPless, 2014-09-21 to round-trip properly
+ *
  * Features / attributes:
  * - provides strongly typed node classes and lists / dictionaries
  * - provides easy access to class members / array items / data values
@@ -63,125 +64,159 @@
 using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
-
-
+using System.Text;
+
 namespace SimpleJSON
 {
     public enum JSONBinaryTag
     {
-        Array            = 1,
-        Class            = 2,
-        Value            = 3,
-        IntValue        = 4,
-        DoubleValue        = 5,
-        BoolValue        = 6,
-        FloatValue        = 7,
+        Array = 1,
+        Class = 2,
+        Value = 3,
+        IntValue = 4,
+        DoubleValue = 5,
+        BoolValue = 6,
+        FloatValue = 7,
     }
-
-    public class JSONNode
+
+    public abstract partial class JSONNode
     {
-        protected enum BasicType { INT, FLOAT, DOUBLE, BOOL, STRING };
-        protected BasicType type = BasicType.STRING;
-
         #region common interface
-        public virtual void Add(string aKey, JSONNode aItem){ }
-        public virtual JSONNode this[int aIndex]   { get { return null; } set { } }
-        public virtual JSONNode this[string aKey]  { get { return null; } set { } }
-        public virtual string Value                { get { return "";   } set { } }
-        public virtual int Count                   { get { return 0;    } }
-
+
+        public virtual void Add(string aKey, JSONNode aItem)
+        {
+        }
+
+        public virtual JSONNode this[int aIndex] { get { return null; } set { } }
+
+        public virtual JSONNode this[string aKey] { get { return null; } set { } }
+
+        public virtual string Value { get { return ""; } set { } }
+
+        public virtual int Count { get { return 0; } }
+
         public virtual void Add(JSONNode aItem)
         {
             Add("", aItem);
         }
-
-        public virtual JSONNode Remove(string aKey) { return null; }
-        public virtual JSONNode Remove(int aIndex) { return null; }
-        public virtual JSONNode Remove(JSONNode aNode) { return aNode; }
-
-        public virtual IEnumerable<JSONNode> Childs { get { yield break;} }
-        public IEnumerable<JSONNode> DeepChilds
-        {
-            get
-            {
-                foreach (var C in Childs)
-                    foreach (var D in C.DeepChilds)
+
+        public virtual JSONNode Remove(string aKey)
+        {
+            return null;
+        }
+
+        public virtual JSONNode Remove(int aIndex)
+        {
+            return null;
+        }
+
+        public virtual JSONNode Remove(JSONNode aNode)
+        {
+            return aNode;
+        }
+
+        public virtual IEnumerable<JSONNode> Children
+        {
+            get
+            {
+                yield break;
+            }
+        }
+
+        public IEnumerable<JSONNode> DeepChildren
+        {
+            get
+            {
+                foreach (var C in Children)
+                    foreach (var D in C.DeepChildren)
                         yield return D;
             }
         }
-
+
         public override string ToString()
         {
             return "JSONNode";
         }
+
         public virtual string ToString(string aPrefix)
         {
             return "JSONNode";
         }
-
+
+        public abstract string ToJSON(int prefix);
+
         #endregion common interface
-
+
         #region typecasting properties
+
+        public virtual JSONBinaryTag Tag { get; set; }
+
         public virtual int AsInt
         {
             get
             {
                 int v = 0;
-                if (int.TryParse(Value,out v))
+                if (int.TryParse(Value, out v))
                     return v;
                 return 0;
             }
             set
             {
                 Value = value.ToString();
-                type = BasicType.INT;
-            }
-        }
+                Tag = JSONBinaryTag.IntValue;
+            }
+        }
+
         public virtual float AsFloat
         {
             get
             {
                 float v = 0.0f;
-                if (float.TryParse(Value,out v))
+                if (float.TryParse(Value, out v))
                     return v;
                 return 0.0f;
             }
             set
             {
                 Value = value.ToString();
-                type = BasicType.FLOAT;
-            }
-        }
+                Tag = JSONBinaryTag.FloatValue;
+            }
+        }
+
         public virtual double AsDouble
         {
             get
             {
                 double v = 0.0;
-                if (double.TryParse(Value,out v))
+                if (double.TryParse(Value, out v))
                     return v;
                 return 0.0;
             }
             set
             {
                 Value = value.ToString();
-                type = BasicType.DOUBLE;
-            }
-        }
+                Tag = JSONBinaryTag.DoubleValue;
+
+            }
+        }
+
         public virtual bool AsBool
         {
             get
             {
                 bool v = false;
-                if (bool.TryParse(Value,out v))
+                if (bool.TryParse(Value, out v))
                     return v;
                 return !string.IsNullOrEmpty(Value);
             }
             set
             {
-                Value = (value)?"true":"false";
-                type = BasicType.BOOL;
-            }
-        }
+                Value = (value) ? "true" : "false";
+                Tag = JSONBinaryTag.BoolValue;
+
+            }
+        }
+
         public virtual JSONArray AsArray
         {
             get
@@ -189,6 +224,7 @@
                 return this as JSONArray;
             }
         }
+
         public virtual JSONClass AsObject
         {
             get
@@ -196,70 +232,137 @@
                 return this as JSONClass;
             }
         }
-
-
+
+
         #endregion typecasting properties
-
+
         #region operators
+
         public static implicit operator JSONNode(string s)
         {
             return new JSONData(s);
         }
+
         public static implicit operator string(JSONNode d)
         {
-            return (d == null)?null:d.Value;
-        }
+            return (d == null) ? null : d.Value;
+        }
+
         public static bool operator ==(JSONNode a, object b)
         {
             if (b == null && a is JSONLazyCreator)
                 return true;
-            return System.Object.ReferenceEquals(a,b);
-        }
-
+            return System.Object.ReferenceEquals(a, b);
+        }
+
         public static bool operator !=(JSONNode a, object b)
         {
             return !(a == b);
         }
-        public override bool Equals (object obj)
+
+        public override bool Equals(object obj)
         {
             return System.Object.ReferenceEquals(this, obj);
         }
-        public override int GetHashCode ()
+
+        public override int GetHashCode()
         {
             return base.GetHashCode();
         }
-
-
+
         #endregion operators
-
+
         internal static string Escape(string aText)
         {
             string result = "";
-            foreach(char c in aText)
-            {
-                switch(c)
+            foreach (char c in aText)
+            {
+                switch (c)
                 {
-                    case '\\' : result += "\\\\"; break;
-                    case '\"' : result += "\\\""; break;
-                    case '\n' : result += "\\n" ; break;
-                    case '\r' : result += "\\r" ; break;
-                    case '\t' : result += "\\t" ; break;
-                    case '\b' : result += "\\b" ; break;
-                    case '\f' : result += "\\f" ; break;
-                    default   : result += c     ; break;
+                    case '\\':
+                        result += "\\\\";
+                        break;
+                    case '\"':
+                        result += "\\\"";
+                        break;
+                    case '\n':
+                        result += "\\n";
+                        break;
+                    case '\r':
+                        result += "\\r";
+                        break;
+                    case '\t':
+                        result += "\\t";
+                        break;
+                    case '\b':
+                        result += "\\b";
+                        break;
+                    case '\f':
+                        result += "\\f";
+                        break;
+                    default:
+                        result += c;
+                        break;
                 }
             }
             return result;
         }
-
+
+        static JSONData Numberize(string token)
+        {
+            bool flag = false;
+            int integer = 0;
+            double real = 0;
+
+            token = token.Replace(".", ",");
+
+            if (int.TryParse(token, out integer))
+            {
+                return new JSONData(integer);
+            }
+
+            if (double.TryParse(token, out real))
+            {
+                return new JSONData(real);
+            }
+
+            if (bool.TryParse(token, out flag))
+            {
+                return new JSONData(flag);
+            }
+
+            throw new NotImplementedException(token);
+        }
+
+        static void AddElement(JSONNode ctx, string token, string tokenName, bool tokenIsString)
+        {
+            if (tokenIsString)
+            {
+                if (ctx is JSONArray)
+                    ctx.Add(token);
+                else
+                    ctx.Add(tokenName, token); // assume dictionary/object
+            }
+            else
+            {
+                JSONData number = Numberize(token);
+                if (ctx is JSONArray)
+                    ctx.Add(number);
+                else
+                    ctx.Add(tokenName, number);
+
+            }
+        }
+
         public static JSONNode Parse(string aJSON)
         {
             Stack<JSONNode> stack = new Stack<JSONNode>();
             JSONNode ctx = null;
             int i = 0;
-            string Token = "";
-            string TokenName = "";
+            StringBuilder Token = new StringBuilder();
+            StringBuilder TokenName = new StringBuilder();
             bool QuoteMode = false;
+            bool TokenIsString = false;
             while (i < aJSON.Length)
             {
                 switch (aJSON[i])
@@ -267,110 +370,111 @@
                     case '{':
                         if (QuoteMode)
                         {
-                            Token += aJSON[i];
+                            Token.Append(aJSON[i]);
                             break;
                         }
                         stack.Push(new JSONClass());
                         if (ctx != null)
                         {
-                            TokenName = TokenName.Trim();
+                            string tmpName = TokenName.ToString().Trim();
                             if (ctx is JSONArray)
                                 ctx.Add(stack.Peek());
-                            else if (TokenName != "")
-                                ctx.Add(TokenName,stack.Peek());
+                            else if (tmpName != "")
+                                ctx.Add(tmpName, stack.Peek());
                         }
-                        TokenName = "";
-                        Token = "";
+                        TokenName.Length = 0;
+                        Token.Length = 0;
                         ctx = stack.Peek();
-                    break;
-
+                        break;
+
                     case '[':
                         if (QuoteMode)
                         {
-                            Token += aJSON[i];
+                            Token.Append(aJSON[i]);
                             break;
                         }
-
+
                         stack.Push(new JSONArray());
                         if (ctx != null)
                         {
-                            TokenName = TokenName.Trim();
+                            string tmpName = TokenName.ToString().Trim();
                             if (ctx is JSONArray)
                                 ctx.Add(stack.Peek());
-                            else if (TokenName != "")
-                                ctx.Add(TokenName,stack.Peek());
+                            else if (tmpName != "")
+                                ctx.Add(tmpName, stack.Peek());
                         }
-                        TokenName = "";
-                        Token = "";
+                        TokenName.Length = 0;
+                        Token.Length = 0;
                         ctx = stack.Peek();
-                    break;
-
+                        break;
+
                     case '}':
                     case ']':
                         if (QuoteMode)
                         {
-                            Token += aJSON[i];
+
+                            Token.Append(aJSON[i]);
                             break;
                         }
                         if (stack.Count == 0)
                             throw new Exception("JSON Parse: Too many closing brackets");
-
+
                         stack.Pop();
-                        if (Token != "")
+                        if (Token.Length > 0)
                         {
-                            TokenName = TokenName.Trim();
-                            if (ctx is JSONArray)
-                                ctx.Add(Token);
-                            else if (TokenName != "")
-                                ctx.Add(TokenName,Token);
+                            string tmpName = TokenName.ToString().Trim();
+                            AddElement(ctx, Token.ToString(), TokenName.ToString(), TokenIsString);
+                            TokenIsString = false;
                         }
-                        TokenName = "";
-                        Token = "";
-                        if (stack.Count>0)
+                        TokenName.Length = 0;
+                        Token.Length = 0;
+                        if (stack.Count > 0)
                             ctx = stack.Peek();
-                    break;
-
+                        break;
+
                     case ':':
                         if (QuoteMode)
                         {
-                            Token += aJSON[i];
+                            Token.Append(aJSON[i]);
                             break;
                         }
-                        TokenName = Token;
-                        Token = "";
-                    break;
-
+                        TokenName.Length = 0;
+                        TokenName.Append(Token);
+                        Token.Length = 0;
+                        TokenIsString = false;
+                        break;
+
                     case '"':
                         QuoteMode ^= true;
-                    break;
-
+                        TokenIsString = QuoteMode == true ? true : TokenIsString;
+                        break;
+
                     case ',':
                         if (QuoteMode)
                         {
-                            Token += aJSON[i];
+                            Token.Append(aJSON[i]);
                             break;
                         }
-                        if (Token != "")
+                        if (Token.Length > 0)
                         {
-                            if (ctx is JSONArray)
-                                ctx.Add(Token);
-                            else if (TokenName != "")
-                                ctx.Add(TokenName, Token);
+                            AddElement(ctx, Token.ToString(), TokenName.ToString(), TokenIsString);
+                            TokenIsString = false;
                         }
-                        TokenName = "";
-                        Token = "";
-                    break;
-
+                        TokenName.Length = 0;
+                        Token.Length = 0;
+                        TokenIsString = false;
+                        break;
+
                     case '\r':
                     case '\n':
-                    break;
-
+                        break;
+
                     case ' ':
                     case '\t':
                         if (QuoteMode)
-                            Token += aJSON[i];
-                    break;
-
+                            Token.Append(aJSON[i]);
+                        break;
+
                     case '\\':
                         ++i;
                         if (QuoteMode)
@@ -378,26 +482,40 @@
                             char C = aJSON[i];
                             switch (C)
                             {
-                                case 't' : Token += '\t'; break;
-                                case 'r' : Token += '\r'; break;
-                                case 'n' : Token += '\n'; break;
-                                case 'b' : Token += '\b'; break;
-                                case 'f' : Token += '\f'; break;
+                                case 't':
+                                    Token.Append('\t');
+                                    break;
+                                case 'r':
+                                    Token.Append('\r');
+                                    break;
+                                case 'n':
+                                    Token.Append('\n');
+                                    break;
+                                case 'b':
+                                    Token.Append('\b');
+                                    break;
+                                case 'f':
+                                    Token.Append('\f');
+                                    break;
                                 case 'u':
-                                {
-                                    string s = aJSON.Substring(i+1,4);
-                                    Token += (char)int.Parse(s, System.Globalization.NumberStyles.AllowHexSpecifier);
-                                    i += 4;
+                                    {
+                                        string s = aJSON.Substring(i + 1, 4);
+                                        Token.Append((char)int.Parse(
+                                            s,
+                                            System.Globalization.NumberStyles.AllowHexSpecifier));
+                                        i += 4;
+                                        break;
+                                    }
+                                default:
+                                    Token.Append(C);
                                     break;
-                                }
-                                default  : Token += C; break;
                             }
                         }
-                    break;
-
+                        break;
+
                     default:
-                        Token += aJSON[i];
-                    break;
+                        Token.Append(aJSON[i]);
+                        break;
                 }
                 ++i;
             }
@@ -407,235 +525,48 @@
             }
             return ctx;
         }
-
-        public virtual void Serialize(System.IO.BinaryWriter aWriter) {}
-
-        public void SaveToStream(System.IO.Stream aData)
-        {
-            var W = new System.IO.BinaryWriter(aData);
-            Serialize(W);
-        }
-
-        #if USE_SharpZipLib
-        public void SaveToCompressedStream(System.IO.Stream aData)
-        {
-            using (var gzipOut = new ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(aData))
-            {
-                gzipOut.IsStreamOwner = false;
-                SaveToStream(gzipOut);
-                gzipOut.Close();
-            }
-        }
-
-        public void SaveToCompressedFile(string aFileName)
-        {
-            #if USE_FileIO
-            System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName);
-            using(var F = System.IO.File.OpenWrite(aFileName))
-            {
-                SaveToCompressedStream(F);
-            }
-            #else
-            throw new Exception("Can't use File IO stuff in webplayer");
-            #endif
-        }
-        public string SaveToCompressedBase64()
-        {
-            using (var stream = new System.IO.MemoryStream())
-            {
-                SaveToCompressedStream(stream);
-                stream.Position = 0;
-                return System.Convert.ToBase64String(stream.ToArray());
-            }
-        }
-
-        #else
-        public void SaveToCompressedStream(System.IO.Stream aData)
-        {
-            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
-        }
-        public void SaveToCompressedFile(string aFileName)
-        {
-            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
-        }
-        public string SaveToCompressedBase64()
-        {
-            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
-        }
-        #endif
-
-        public void SaveToFile(string aFileName)
-        {
-            #if USE_FileIO
-            System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName);
-            using(var F = System.IO.File.OpenWrite(aFileName))
-            {
-                SaveToStream(F);
-            }
-            #else
-            throw new Exception("Can't use File IO stuff in webplayer");
-            #endif
-        }
-        public string SaveToBase64()
-        {
-            using (var stream = new System.IO.MemoryStream())
-            {
-                SaveToStream(stream);
-                stream.Position = 0;
-                return System.Convert.ToBase64String(stream.ToArray());
-            }
-        }
-        public static JSONNode Deserialize(System.IO.BinaryReader aReader)
-        {
-            JSONBinaryTag type = (JSONBinaryTag)aReader.ReadByte();
-            switch(type)
-            {
-            case JSONBinaryTag.Array:
-            {
-                int count = aReader.ReadInt32();
-                JSONArray tmp = new JSONArray();
-                for(int i = 0; i < count; i++)
-                    tmp.Add(Deserialize(aReader));
-                return tmp;
-            }
-            case JSONBinaryTag.Class:
-            {
-                int count = aReader.ReadInt32();
-                JSONClass tmp = new JSONClass();
-                for(int i = 0; i < count; i++)
-                {
-                    string key = aReader.ReadString();
-                    var val = Deserialize(aReader);
-                    tmp.Add(key, val);
-                }
-                return tmp;
-            }
-            case JSONBinaryTag.Value:
-            {
-                return new JSONData(aReader.ReadString());
-            }
-            case JSONBinaryTag.IntValue:
-            {
-                return new JSONData(aReader.ReadInt32());
-            }
-            case JSONBinaryTag.DoubleValue:
-            {
-                return new JSONData(aReader.ReadDouble());
-            }
-            case JSONBinaryTag.BoolValue:
-            {
-                return new JSONData(aReader.ReadBoolean());
-            }
-            case JSONBinaryTag.FloatValue:
-            {
-                return new JSONData(aReader.ReadSingle());
-            }
-
-            default:
-            {
-                throw new Exception("Error deserializing JSON. Unknown tag: " + type);
-            }
-            }
-        }
-
-        #if USE_SharpZipLib
-        public static JSONNode LoadFromCompressedStream(System.IO.Stream aData)
-        {
-            var zin = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(aData);
-            return LoadFromStream(zin);
-        }
-        public static JSONNode LoadFromCompressedFile(string aFileName)
-        {
-            #if USE_FileIO
-            using(var F = System.IO.File.OpenRead(aFileName))
-            {
-                return LoadFromCompressedStream(F);
-            }
-            #else
-            throw new Exception("Can't use File IO stuff in webplayer");
-            #endif
-        }
-        public static JSONNode LoadFromCompressedBase64(string aBase64)
-        {
-            var tmp = System.Convert.FromBase64String(aBase64);
-            var stream = new System.IO.MemoryStream(tmp);
-            stream.Position = 0;
-            return LoadFromCompressedStream(stream);
-        }
-        #else
-        public static JSONNode LoadFromCompressedFile(string aFileName)
-        {
-            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
-        }
-        public static JSONNode LoadFromCompressedStream(System.IO.Stream aData)
-        {
-            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
-        }
-        public static JSONNode LoadFromCompressedBase64(string aBase64)
-        {
-            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
-        }
-        #endif
-
-        public static JSONNode LoadFromStream(System.IO.Stream aData)
-        {
-            using(var R = new System.IO.BinaryReader(aData))
-            {
-                return Deserialize(R);
-            }
-        }
-        public static JSONNode LoadFromFile(string aFileName)
-        {
-            #if USE_FileIO
-            using(var F = System.IO.File.OpenRead(aFileName))
-            {
-                return LoadFromStream(F);
-            }
-            #else
-            throw new Exception("Can't use File IO stuff in webplayer");
-            #endif
-        }
-        public static JSONNode LoadFromBase64(string aBase64)
-        {
-            var tmp = System.Convert.FromBase64String(aBase64);
-            var stream = new System.IO.MemoryStream(tmp);
-            stream.Position = 0;
-            return LoadFromStream(stream);
-        }
-    } // End of JSONNode
-
+
+    }
+    // End of JSONNode
+
     public class JSONArray : JSONNode, IEnumerable
     {
         private List<JSONNode> m_List = new List<JSONNode>();
+
         public override JSONNode this[int aIndex]
         {
             get
             {
-                if (aIndex<0 || aIndex >= m_List.Count)
+                if (aIndex < 0 || aIndex >= m_List.Count)
                     return new JSONLazyCreator(this);
                 return m_List[aIndex];
             }
             set
             {
-                if (aIndex<0 || aIndex >= m_List.Count)
+                if (aIndex < 0 || aIndex >= m_List.Count)
                     m_List.Add(value);
                 else
                     m_List[aIndex] = value;
             }
         }
+
         public override JSONNode this[string aKey]
         {
-            get{ return new JSONLazyCreator(this);}
-            set{ m_List.Add(value); }
-        }
+            get { return new JSONLazyCreator(this); }
+            set { m_List.Add(value); }
+        }
+
         public override int Count
         {
             get { return m_List.Count; }
         }
+
+
         public override void Add(string aKey, JSONNode aItem)
         {
             m_List.Add(aItem);
         }
+
         public override JSONNode Remove(int aIndex)
         {
             if (aIndex < 0 || aIndex >= m_List.Count)
@@ -644,24 +575,28 @@
             m_List.RemoveAt(aIndex);
             return tmp;
         }
+
         public override JSONNode Remove(JSONNode aNode)
         {
             m_List.Remove(aNode);
             return aNode;
         }
-        public override IEnumerable<JSONNode> Childs
-        {
-            get
-            {
-                foreach(JSONNode N in m_List)
+
+        public override IEnumerable<JSONNode> Children
+        {
+            get
+            {
+                foreach (JSONNode N in m_List)
                     yield return N;
             }
         }
+
         public IEnumerator GetEnumerator()
         {
-            foreach(JSONNode N in m_List)
+            foreach (JSONNode N in m_List)
                 yield return N;
         }
+
         public override string ToString()
         {
             string result = "[ ";
@@ -674,6 +609,7 @@
             result += " ]";
             return result;
         }
+
         public override string ToString(string aPrefix)
         {
             string result = "[ ";
@@ -681,26 +617,35 @@
             {
                 if (result.Length > 3)
                     result += ", ";
-                result += "\n" + aPrefix + "   ";
-                result += N.ToString(aPrefix+"   ");
+                result += "\n" + aPrefix + "   ";
+                result += N.ToString(aPrefix + "   ");
             }
             result += "\n" + aPrefix + "]";
             return result;
         }
-        public override void Serialize (System.IO.BinaryWriter aWriter)
-        {
-            aWriter.Write((byte)JSONBinaryTag.Array);
-            aWriter.Write(m_List.Count);
-            for(int i = 0; i < m_List.Count; i++)
-            {
-                m_List[i].Serialize(aWriter);
-            }
-        }
-    } // End of JSONArray
-
+
+        public override string ToJSON(int prefix)
+        {
+            string s = new string(' ', (prefix + 1) * 2);
+            string ret = "[ ";
+            foreach (JSONNode n in m_List)
+            {
+                if (ret.Length > 3)
+                    ret += ", ";
+                ret += "\n" + s;
+                ret += n.ToJSON(prefix + 1);
+
+            }
+            ret += "\n" + s + "]";
+            return ret;
+        }
+    }
+    // End of JSONArray
+
     public class JSONClass : JSONNode, IEnumerable
     {
-        private Dictionary<string,JSONNode> m_Dict = new Dictionary<string,JSONNode>();
+        private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>();
+
         public override JSONNode this[string aKey]
         {
             get
@@ -715,9 +660,10 @@
                 if (m_Dict.ContainsKey(aKey))
                     m_Dict[aKey] = value;
                 else
-                    m_Dict.Add(aKey,value);
-            }
-        }
+                    m_Dict.Add(aKey, value);
+            }
+        }
+
         public override JSONNode this[int aIndex]
         {
             get
@@ -734,12 +680,12 @@
                 m_Dict[key] = value;
             }
         }
+
         public override int Count
         {
             get { return m_Dict.Count; }
         }
-
-
+
         public override void Add(string aKey, JSONNode aItem)
         {
             if (!string.IsNullOrEmpty(aKey))
@@ -752,15 +698,16 @@
             else
                 m_Dict.Add(Guid.NewGuid().ToString(), aItem);
         }
-
+
         public override JSONNode Remove(string aKey)
         {
             if (!m_Dict.ContainsKey(aKey))
                 return null;
             JSONNode tmp = m_Dict[aKey];
             m_Dict.Remove(aKey);
-            return tmp;
-        }
+            return tmp;
+        }
+
         public override JSONNode Remove(int aIndex)
         {
             if (aIndex < 0 || aIndex >= m_Dict.Count)
@@ -769,6 +716,7 @@
             m_Dict.Remove(item.Key);
             return item.Value;
         }
+
         public override JSONNode Remove(JSONNode aNode)
         {
             try
@@ -782,21 +730,22 @@
                 return null;
             }
         }
-
-        public override IEnumerable<JSONNode> Childs
-        {
-            get
-            {
-                foreach(KeyValuePair<string,JSONNode> N in m_Dict)
+
+        public override IEnumerable<JSONNode> Children
+        {
+            get
+            {
+                foreach (KeyValuePair<string, JSONNode> N in m_Dict)
                     yield return N.Value;
             }
         }
-
+
         public IEnumerator GetEnumerator()
         {
-            foreach(KeyValuePair<string, JSONNode> N in m_Dict)
+            foreach (KeyValuePair<string, JSONNode> N in m_Dict)
                 yield return N;
         }
+
         public override string ToString()
         {
             string result = "{";
@@ -809,6 +758,7 @@
             result += "}";
             return result;
         }
+
         public override string ToString(string aPrefix)
         {
             string result = "{ ";
@@ -817,134 +767,115 @@
                 if (result.Length > 3)
                     result += ", ";
                 result += "\n" + aPrefix + "   ";
-                result += "\"" + Escape(N.Key) + "\" : " + N.Value.ToString(aPrefix+"   ");
+                result += "\"" + Escape(N.Key) + "\" : " + N.Value.ToString(aPrefix + "   ");
             }
             result += "\n" + aPrefix + "}";
             return result;
         }
-        public override void Serialize (System.IO.BinaryWriter aWriter)
-        {
-            aWriter.Write((byte)JSONBinaryTag.Class);
-            aWriter.Write(m_Dict.Count);
-            foreach(string K in m_Dict.Keys)
-            {
-                aWriter.Write(K);
-                m_Dict[K].Serialize(aWriter);
-            }
-        }
-    } // End of JSONClass
-
+
+        public override string ToJSON(int prefix)
+        {
+            string s = new string(' ', (prefix + 1) * 2);
+            string ret = "{ ";
+            foreach (KeyValuePair<string, JSONNode> n in m_Dict)
+            {
+                if (ret.Length > 3)
+                    ret += ", ";
+                ret += "\n" + s;
+                ret += string.Format("\"{0}\": {1}", n.Key, n.Value.ToJSON(prefix + 1));
+            }
+            ret += "\n" + s + "}";
+            return ret;
+        }
+    }
+    // End of JSONClass
+
     public class JSONData : JSONNode
     {
-
         private string m_Data;
+
+
         public override string Value
         {
             get { return m_Data; }
-            set { m_Data = value; }
-        }
+            set
+            {
+                m_Data = value;
+                Tag = JSONBinaryTag.Value;
+            }
+        }
+
         public JSONData(string aData)
         {
             m_Data = aData;
-        }
+            Tag = JSONBinaryTag.Value;
+        }
+
         public JSONData(float aData)
         {
-            type = BasicType.FLOAT;
             AsFloat = aData;
         }
+
         public JSONData(double aData)
         {
-            type = BasicType.DOUBLE;
             AsDouble = aData;
         }
+
         public JSONData(bool aData)
         {
-            type = BasicType.BOOL;
             AsBool = aData;
         }
+
         public JSONData(int aData)
         {
-            type = BasicType.INT;
             AsInt = aData;
         }
-
+
         public override string ToString()
         {
-            string val = m_Data != null ? m_Data : Value;
-
-            switch (type)
-            {
-                case BasicType.BOOL:
-                    return AsBool ? "true" : "false";
-                case BasicType.INT:
-                    return AsInt.ToString();
-                case BasicType.DOUBLE:
-                    return AsDouble.ToString();
-                case BasicType.FLOAT:
-                    return AsFloat.ToString();
-                case BasicType.STRING:
+            return "\"" + Escape(m_Data) + "\"";
+        }
+
+        public override string ToString(string aPrefix)
+        {
+            return "\"" + Escape(m_Data) + "\"";
+        }
+
+        public override string ToJSON(int prefix)
+        {
+            switch (Tag)
+            {
+                case JSONBinaryTag.DoubleValue:
+                case JSONBinaryTag.FloatValue:
+                case JSONBinaryTag.IntValue:
+                case JSONBinaryTag.BoolValue:
+                    return m_Data.Replace(",", ".");
+                case JSONBinaryTag.Value:
+                    return string.Format("\"{0}\"", Escape(m_Data));
                 default:
-                    return "\"" + Escape(val) + "\"";
-            }
-        }
-        public override string ToString(string aPrefix)
-        {
-            return "\"" + Escape(m_Data) + "\"";
-        }
-        public override void Serialize (System.IO.BinaryWriter aWriter)
-        {
-            var tmp = new JSONData("");
-
-            tmp.AsInt = AsInt;
-            if (tmp.m_Data == this.m_Data)
-            {
-                aWriter.Write((byte)JSONBinaryTag.IntValue);
-                aWriter.Write(AsInt);
-                return;
-            }
-            tmp.AsFloat = AsFloat;
-            if (tmp.m_Data == this.m_Data)
-            {
-                aWriter.Write((byte)JSONBinaryTag.FloatValue);
-                aWriter.Write(AsFloat);
-                return;
-            }
-            tmp.AsDouble = AsDouble;
-            if (tmp.m_Data == this.m_Data)
-            {
-                aWriter.Write((byte)JSONBinaryTag.DoubleValue);
-                aWriter.Write(AsDouble);
-                return;
-            }
-
-            tmp.AsBool = AsBool;
-            if (tmp.m_Data == this.m_Data)
-            {
-                aWriter.Write((byte)JSONBinaryTag.BoolValue);
-                aWriter.Write(AsBool);
-                return;
-            }
-            aWriter.Write((byte)JSONBinaryTag.Value);
-            aWriter.Write(m_Data);
-        }
-    } // End of JSONData
-
+                    throw new NotSupportedException("This shouldn't be here: " + Tag.ToString());
+            }
+        }
+    }
+    // End of JSONData
+
     internal class JSONLazyCreator : JSONNode
     {
         private JSONNode m_Node = null;
         private string m_Key = null;
-
+
         public JSONLazyCreator(JSONNode aNode)
         {
             m_Node = aNode;
-            m_Key  = null;
-        }
+            m_Key = null;
+        }
+
         public JSONLazyCreator(JSONNode aNode, string aKey)
         {
             m_Node = aNode;
             m_Key = aKey;
         }
-
+
         private void Set(JSONNode aVal)
         {
             if (m_Key == null)
@@ -957,7 +888,7 @@
             }
             m_Node = null; // Be GC friendly.
         }
-
+
         public override JSONNode this[int aIndex]
         {
             get
@@ -971,7 +902,7 @@
                 Set(tmp);
             }
         }
-
+
         public override JSONNode this[string aKey]
         {
             get
@@ -985,49 +916,60 @@
                 Set(tmp);
             }
         }
-        public override void Add (JSONNode aItem)
+
+        public override void Add(JSONNode aItem)
         {
             var tmp = new JSONArray();
             tmp.Add(aItem);
             Set(tmp);
         }
-        public override void Add (string aKey, JSONNode aItem)
+
+        public override void Add(string aKey, JSONNode aItem)
         {
             var tmp = new JSONClass();
             tmp.Add(aKey, aItem);
             Set(tmp);
         }
+
         public static bool operator ==(JSONLazyCreator a, object b)
         {
             if (b == null)
                 return true;
-            return System.Object.ReferenceEquals(a,b);
-        }
-
+            return System.Object.ReferenceEquals(a, b);
+        }
+
         public static bool operator !=(JSONLazyCreator a, object b)
         {
             return !(a == b);
         }
-        public override bool Equals (object obj)
+
+        public override bool Equals(object obj)
         {
             if (obj == null)
                 return true;
             return System.Object.ReferenceEquals(this, obj);
         }
-        public override int GetHashCode ()
+
+        public override int GetHashCode()
         {
             return base.GetHashCode();
         }
-
+
         public override string ToString()
         {
             return "";
         }
+
         public override string ToString(string aPrefix)
         {
             return "";
         }
-
+
+        public override string ToJSON(int prefix)
+        {
+            return "";
+        }
+
         public override int AsInt
         {
             get
@@ -1039,10 +981,10 @@
             set
             {
                 JSONData tmp = new JSONData(value);
-                type = BasicType.INT;
-                Set(tmp);
-            }
-        }
+                Set(tmp);
+            }
+        }
+
         public override float AsFloat
         {
             get
@@ -1054,16 +996,15 @@
             set
             {
                 JSONData tmp = new JSONData(value);
-                type = BasicType.FLOAT;
-                Set(tmp);
-            }
-        }
+                Set(tmp);
+            }
+        }
+
         public override double AsDouble
         {
             get
             {
                 JSONData tmp = new JSONData(0.0);
-                type = BasicType.DOUBLE;
                 Set(tmp);
                 return 0.0;
             }
@@ -1073,22 +1014,22 @@
                 Set(tmp);
             }
         }
+
         public override bool AsBool
         {
             get
             {
                 JSONData tmp = new JSONData(false);
-                type = BasicType.BOOL;
                 Set(tmp);
                 return false;
             }
             set
             {
                 JSONData tmp = new JSONData(value);
-                type = BasicType.STRING;
-                Set(tmp);
-            }
-        }
+                Set(tmp);
+            }
+        }
+
         public override JSONArray AsArray
         {
             get
@@ -1098,6 +1039,7 @@
                 return tmp;
             }
         }
+
         public override JSONClass AsObject
         {
             get
@@ -1107,8 +1049,9 @@
                 return tmp;
             }
         }
-    } // End of JSONLazyCreator
-
+    }
+    // End of JSONLazyCreator
+
     public static class JSON
     {
         public static JSONNode Parse(string aJSON)