protected override void ReadFromImpl(object obj)
        {
            ClearReferencesCache();

            Scene scene = (Scene)obj;

            GameObject[] rootGameObjects;
            if (scene.IsValid())
            {
                rootGameObjects = scene.GetRootGameObjects();
            }
            else
            {
                rootGameObjects = new GameObject[0];
            }

            List <PersistentObject>     data            = new List <PersistentObject>();
            List <long>                 identifiers     = new List <long>();
            List <PersistentDescriptor> descriptors     = new List <PersistentDescriptor>(rootGameObjects.Length);
            GetDepsFromContext          getSceneDepsCtx = new GetDepsFromContext();

            for (int i = 0; i < rootGameObjects.Length; ++i)
            {
                GameObject           rootGO     = rootGameObjects[i];
                PersistentDescriptor descriptor = CreateDescriptorAndData(rootGO, data, identifiers, getSceneDepsCtx);
                if (descriptor != null)
                {
                    descriptors.Add(descriptor);
                }
            }

            HashSet <object> allDeps = getSceneDepsCtx.Dependencies;

            Queue <UnityObject> depsQueue = new Queue <UnityObject>(allDeps.OfType <UnityObject>());

            List <PersistentObject> assets = new List <PersistentObject>();
            List <int> assetIdentifiers    = new List <int>();

            GetDepsFromContext getDepsCtx = new GetDepsFromContext();

            while (depsQueue.Count > 0)
            {
                UnityObject uo = depsQueue.Dequeue();
                if (!uo)
                {
                    continue;
                }


                Type persistentType = m_typeMap.ToPersistentType(uo.GetType());
                if (persistentType != null)
                {
                    getDepsCtx.Clear();

                    try
                    {
                        PersistentObject persistentObject = (PersistentObject)Activator.CreateInstance(persistentType);
                        if (!(uo is GameObject) && !(uo is Component))
                        {
                            if (!m_assetDB.IsMapped(uo))
                            {
                                if (uo is Texture2D)
                                {
                                    Texture2D texture = (Texture2D)uo;
                                    if (texture.isReadable)  //
                                    {
                                        persistentObject.ReadFrom(uo);
                                        assets.Add(persistentObject);
                                        assetIdentifiers.Add(uo.GetInstanceID());
                                        persistentObject.GetDepsFrom(uo, getDepsCtx);
                                    }
                                }
                                else
                                {
                                    persistentObject.ReadFrom(uo);
                                    assets.Add(persistentObject);
                                    assetIdentifiers.Add(uo.GetInstanceID());
                                    persistentObject.GetDepsFrom(uo, getDepsCtx);
                                }
                            }
                            else
                            {
                                persistentObject.GetDepsFrom(uo, getDepsCtx);
                            }
                        }
                        else
                        {
                            persistentObject.GetDepsFrom(uo, getDepsCtx);
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e.ToString());
                    }

                    foreach (UnityObject dep in getDepsCtx.Dependencies)
                    {
                        if (!allDeps.Contains(dep))
                        {
                            allDeps.Add(dep);
                            depsQueue.Enqueue(dep);
                        }
                    }
                }
            }

            List <UnityObject> externalDeps = new List <UnityObject>(allDeps.OfType <UnityObject>());

            for (int i = externalDeps.Count - 1; i >= 0; i--)
            {
                if (!m_assetDB.IsMapped(externalDeps[i]))
                {
                    externalDeps.RemoveAt(i);
                }
            }

            Descriptors  = descriptors.ToArray();
            Identifiers  = identifiers.ToArray();
            Data         = data.ToArray();
            Dependencies = externalDeps.Select(uo => m_assetDB.ToID(uo)).ToArray();

            Assets           = assets.ToArray();
            AssetIdentifiers = assetIdentifiers.ToArray();

            ClearReferencesCache();
        }
        protected override void ReadFromImpl(object obj)
        {
            ClearReferencesCache();

            Scene scene = (Scene)obj;

            GameObject[] rootGameObjects;
            if (scene.IsValid())
            {
                rootGameObjects = scene.GetRootGameObjects();
            }
            else
            {
                rootGameObjects = new GameObject[0];
            }

            List <Tuple <PersistentObject <TID>, UnityObject> > data = new List <Tuple <PersistentObject <TID>, UnityObject> >();
            List <TID> identifiers = new List <TID>();
            List <PersistentDescriptor <TID> > descriptors = new List <PersistentDescriptor <TID> >(rootGameObjects.Length);
            GetDepsFromContext getSceneDepsCtx             = new GetDepsFromContext();

            for (int i = 0; i < rootGameObjects.Length; ++i)
            {
                GameObject rootGO = rootGameObjects[i];
                PersistentDescriptor <TID> descriptor = CreateDescriptorAndData(rootGO, data, identifiers, getSceneDepsCtx);
                if (descriptor != null)
                {
                    descriptors.Add(descriptor);
                }
            }

            HashSet <object>    allDeps   = getSceneDepsCtx.Dependencies;
            Queue <UnityObject> depsQueue = new Queue <UnityObject>(allDeps.OfType <UnityObject>());
            List <Tuple <PersistentObject <TID>, UnityObject> > assets = new List <Tuple <PersistentObject <TID>, UnityObject> >();
            List <TID> assetIds = new List <TID>();

            GetDepsFromContext getDepsCtx = new GetDepsFromContext();

            while (depsQueue.Count > 0)
            {
                UnityObject uo = depsQueue.Dequeue();
                if (!uo)
                {
                    continue;
                }


                Type persistentType = m_typeMap.ToPersistentType(uo.GetType());
                if (persistentType != null)
                {
                    getDepsCtx.Clear();

                    try
                    {
                        PersistentObject <TID> persistentObject = (PersistentObject <TID>)Activator.CreateInstance(persistentType);
                        if (!(uo is GameObject) && !(uo is Component) && (uo.hideFlags & HideFlags.DontSave) == 0)
                        {
                            if (!m_assetDB.IsMapped(uo))
                            {
                                assets.Add(new Tuple <PersistentObject <TID>, UnityObject>(persistentObject, uo));
                                assetIds.Add(ToID(uo));
                                persistentObject.GetDepsFrom(uo, getDepsCtx);
                            }
                            else
                            {
                                persistentObject.GetDepsFrom(uo, getDepsCtx);
                            }
                        }
                        else
                        {
                            persistentObject.GetDepsFrom(uo, getDepsCtx);
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e.ToString());
                    }

                    foreach (UnityObject dep in getDepsCtx.Dependencies)
                    {
                        if (!allDeps.Contains(dep))
                        {
                            allDeps.Add(dep);
                            depsQueue.Enqueue(dep);
                        }
                    }
                }
            }

            List <UnityObject> externalDeps = new List <UnityObject>(allDeps.OfType <UnityObject>());

            for (int i = externalDeps.Count - 1; i >= 0; i--)
            {
                if (!m_assetDB.IsMapped(externalDeps[i]))
                {
                    externalDeps.RemoveAt(i);
                }
            }

            Descriptors = descriptors.ToArray();
            Identifiers = identifiers.ToArray();
            Data        = data.Select(t =>
            {
                PersistentObject <TID> persistentObject = t.Item1;
                persistentObject.ReadFrom(t.Item2);
                return(persistentObject);
            }).ToArray();
            Dependencies = externalDeps.Select(uo => ToID(uo)).ToArray();

            Assets = assets.Select(t =>
            {
                PersistentObject <TID> persistentObject = t.Item1;
                persistentObject.ReadFrom(t.Item2);
                return(persistentObject);
            }).ToArray();

            AssetIds = assetIds.ToArray();

            m_assetDB.UnregisterSceneObjects();
            ClearReferencesCache();
        }