static bool FixupDelete(object obj, WeakRefField field, string src)
    {
        bool deleted = false;

        foreach (var weakRefs in field.container.weakRefs)
        {
            var wref = (WeakAssetRef)weakRefs.GetValue(obj);
            if (wref != null)
            {
                if (wref.InspectorConditionalAssetDeleted(src))
                {
                    deleted = true;
                }
            }
        }

        // descend into other container fields.
        foreach (var subField in field.subFields)
        {
            var val = subField.field.GetValue(obj);
            if (val != null)
            {
                deleted = FixupDelete(val, subField, src) || deleted;
            }
        }

        return(deleted);
    }
    static void Descend(Type type, HashSet <Type> inspected, Dictionary <Type, WeakRefContainer> containers, WeakRefField outer, FieldInfo outerField)
    {
        if (type.IsAbstract)
        {
            return;
        }

        if ((outer != null) && typeof(UnityEngine.Object).IsAssignableFrom(type))
        {
            // don't descend into member fields that point to unity objects
            // if they are assets they will be dealt with as root level
            // types
            return;
        }

        var field = new WeakRefField();

        field.field = outerField;

        if (!inspected.Add(type))
        {
            if (containers.TryGetValue(type, out field.container))
            {
                if (outer != null)
                {
                    outer.subFields.Add(field);
                }
            }
            return;
        }

        field.container = new WeakRefContainer();

        for (var innerType = type; (innerType != null) && (innerType != typeof(object)); innerType = innerType.BaseType)
        {
            var fields = innerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            foreach (var f in fields)
            {
                if (typeof(WeakAssetRef).IsAssignableFrom(f.FieldType))
                {
                    field.container.weakRefs.Add(f);
                }
                else
                {
                    Descend(f.FieldType, inspected, containers, field, f);
                }
            }
        }

        if ((field.container.weakRefs.Count > 0) || (field.subFields.Count > 0))
        {
            if (field.container.weakRefs.Count > 0)
            {
                containers.Add(type, field.container);
            }

            if (outer != null)
            {
                outer.subFields.Add(field);
            }
            else
            {
                _classes.Add(type, field);
            }
        }
    }