private void VisitTree(JToken node)
        {
            if (node is JArray arr)
            {
                foreach (var value in arr)
                {
                    VisitTree(value);
                }
                return;
            }

            if (node is JObject obj)
            {
                foreach (var property in obj.Properties())
                {
                    if (string.Equals(property.Name, "$id", StringComparison.Ordinal))
                    {
                        var id          = property.Value.Value <string>();
                        var blueprintId = BlueprintIdentifier.From(obj);
                        AddBlueprintRef(blueprintId, obj);
                        _refs.Add(id, obj);
                    }

                    VisitTree(property.Value);
                }
            }
        }
 public static bool TryGetFactory(BlueprintIdentifier blueprintId, out Func <ModelDataAccessor, object> factory)
 {
     if (BlueprintTypes.TryGetValue(blueprintId, out var type))
     {
         return(UntypedFactories.TryGetValue(type, out factory));
     }
     factory = null;
     return(false);
 }
        private void AddBlueprintRef(BlueprintIdentifier blueprintId, JObject obj)
        {
            if (!Mappings.TryGetFactory(blueprintId, out var factory))
            {
                return;
            }

            if (!_blueprintRefs.TryGetValue(blueprintId, out var list))
            {
                list = new List <Model>();
                _blueprintRefs.Add(blueprintId, list);
            }

            var model = (Model)_refs.CreateObject(obj, factory);

            list.Add(model);
        }