private void RunFixups(ulong id)
        {
            if (Fixes.TryGetValue(id, out HashSet <Fixup> fixes))
            {
                Fixes.Remove(id);
                foreach (Fixup fix in fixes)
                {
                    ulong fixed_id = SerializationChart[fix.Object].Id;
                    SerializationStatus fix_status = fix.Run();
                    switch (fix_status.Result)
                    {
                    case SerializationResult.Success:
                        FixupIDs.Remove(fixed_id);
                        RunFixups(fixed_id);
                        break;

                    case SerializationResult.Failure:
                        break;

                    default:
                        throw new SerializationException("Fix didn't return a valid status!");
                    }
                }
            }
        }
        private object Deserialize(Type t, SerializedObject obj)
        {
            if (ObjectChart.TryGetValue(obj.Id, out object value))
            {
                return(value);
            }

            foreach (ISerializer serializer in Library.GetDeserializers(t))
            {
                SerializationStatus status = serializer.Deserialize(this, t, obj.Info, Context);
                if (status == null)
                {
                    continue;
                }
                switch (status.Result)
                {
                case SerializationResult.Deserialized:
                case SerializationResult.Success:
                {
                    ObjectChart.Add(obj.Id, status.Object);

                    if (!status.Object?.GetType().IsPrimitive ?? false)
                    {
                        SerializationChart.Add(status.Object, obj);
                    }

                    RunFixups(obj.Id);

                    return(status.Object);
                }

                case SerializationResult.NeedsFixing:
                {
                    ObjectChart.Add(obj.Id, status.Object);

                    if (!status.Object?.GetType().IsPrimitive ?? false)
                    {
                        SerializationChart.Add(status.Object, obj);
                    }

                    AddFixup(obj.Id, new Fixup(this, status.Object, status.Fix, status.RequiredIDs));
                    RunFixups(obj.Id);

                    return(status.Object);
                }

                case SerializationResult.UseAlternative:
                    return(Deserialize(status.AltType, obj));
                }
            }

            throw new SerializationException("Object couldn't be deserialized!");
        }
        private SerializedObject Serialize(Type t, object obj, bool run_checks)
        {
            ulong object_id;

            if (run_checks)
            {
                if (obj == null)
                {
                    return(SerializedObject.Null);
                }

                if (SerializationChart.TryGetValue(obj, out SerializedObject value))
                {
                    return(value);
                }

                if (SerializingObjects.TryGetValue(obj, out object_id))
                {
                    return(new SerializedObject(Context, object_id)); // Reference Object
                }
                object_id = ++CurrentId;
            }
            else
            {
                object_id = SerializingObjects[obj];
            }

            SerializingObjects.Add(obj, object_id);

            foreach (ISerializer serializer in Library.GetSerializers(t))
            {
                SerializationInfo   info   = new SerializationInfo(obj.GetType(), new FormatterConverter());
                SerializationStatus status = serializer.Serialize(this, obj, info, Context);

                if (status == null)
                {
                    continue;
                }

                switch (status.Result)
                {
                case SerializationResult.NeedsFixing:
                    throw new SerializationException("Serializer didn't return a valid status!");

                case SerializationResult.Failure:
                    continue;

                case SerializationResult.Success:
                {
                    SerializedObject result = new SerializedObject(info, Context, object_id);
                    SerializationChart.Add(object_id, result);
                    ObjectChart.Add(object_id, obj);
                    SerializingObjects.Remove(obj);
                    return(result);
                }

                case SerializationResult.UseAlternative:
                    return(Serialize(status.AltType, obj, false));

                default:
                    throw new SerializationException("Serializer didn't return a valid status!");
                }
            }

            throw new SerializationException("Unable to serialize object!");
        }