// Return the set of operations needed to make |previousState| look like
        // |currentState|.
        public static void CreateDelta(
            Dictionary <ObjectDataPath[], object> currentState,
            Dictionary <ObjectDataPath[], object> previousState,
            out Dictionary <ObjectDataPath[], object> toAdd,
            out Dictionary <ObjectDataPath[], object> toModify,
            out List <ObjectDataPath[]> toRemove,
            bool dumpString)
        {
            toAdd    = AllocateDict();
            toModify = AllocateDict();
            toRemove = new List <ObjectDataPath[]>();

            foreach (var entry in previousState)
            {
                // End has it, but start doesn't. We need to remove the key.
                if (currentState.ContainsKey(entry.Key) == false)
                {
                    toRemove.Add(entry.Key);
                    continue;
                }

                object startObj = currentState[entry.Key];
                object endObj   = entry.Value;

                // If the objects are the same, do not modify.
                if (ReferenceEquals(startObj, endObj) || startObj.Equals(endObj))
                {
                    continue;
                }

                toModify.Add(entry.Key, startObj);
            }

            // Start has it, but end doesn't.
            foreach (var entry in currentState)
            {
                if (previousState.ContainsKey(entry.Key) == false)
                {
                    toAdd.Add(entry.Key, entry.Value);
                }
            }

            if (dumpString)
            {
                var msg = "Computed delta (click to see):" + Environment.NewLine + Environment.NewLine;
                msg += DumpToString("current", ReadableModel(currentState)) + Environment.NewLine;
                msg += DumpToString("previous", ReadableModel(previousState));
                msg += Environment.NewLine + "----" + Environment.NewLine + Environment.NewLine;
                msg += DumpToString("toAdd", ReadableModel(toAdd)) + Environment.NewLine;
                msg += DumpToString("toModify", ReadableModel(toModify)) + Environment.NewLine;
                msg += DumpToString("toRemove", toRemove.Select(r => ObjectDataPath.ToString(r)).ToList());
                Debug.Log(msg);
            }
        }
        public static Dictionary <string, object> ReadableModel(Dictionary <ObjectDataPath[], object> model)
        {
            var readable = new Dictionary <string, object>();

            foreach (var entry in model)
            {
                string navString = ObjectDataPath.ToString(entry.Key);
                //Debug.Log("Adding " + navString);
                readable.Add(navString, entry.Value);
            }
            return(readable);
        }
 private static string DumpToString(KeyValuePair <ObjectDataPath[], object> property)
 {
     return(ObjectDataPath.ToString(property.Key) + " => " + property.Value);// + " (" + property.Value.GetType() + ")";
 }