/// <summary>
        /// Refresh ObjectReferences, throws NPE for broken ObjectReferences.
        ///
        /// An ObjectReference is considered broken if it's object has been deleted.
        /// </summary>
        /// <param name="instance"></param>
        private void doRemap(GameObject instance)
        {
            Stack <IPropertyContainer> toVisit = new Stack <IPropertyContainer>();

            toVisit.Push(instance);

            while (toVisit.Any())
            {
                IPropertyContainer currentInstance = toVisit.Pop();
                foreach (IProperty property in currentInstance.Properties)
                {
                    switch (property)
                    {
                    case PropertyObject po: {
                        ObjectReference reference = po.Value;
                        if (reference.IsId && reference.ObjectId >= startIndex)
                        {
                            reference.ObjectId = MappedObjects[reference.ObjectId].Id;
                        }
                        break;
                    }

                    case PropertyArray pa: {
                        IArkArray <IStruct>         structList          = pa.GetTypedValue <IStruct>();
                        IArkArray <ObjectReference> objectReferenceList = pa.GetTypedValue <ObjectReference>();
                        if (structList != null)
                        {
                            foreach (IStruct aStruct in structList)
                            {
                                if (aStruct is IPropertyContainer container)
                                {
                                    toVisit.Push(container);
                                }
                            }
                        }
                        else if (objectReferenceList != null)
                        {
                            foreach (ObjectReference reference in objectReferenceList)
                            {
                                if (reference.IsId && reference.ObjectId >= startIndex)
                                {
                                    reference.ObjectId = MappedObjects[reference.ObjectId].Id;
                                }
                            }
                        }
                        break;
                    }

                    case PropertyStruct ps: {
                        IStruct aStruct = ps.Value;
                        if (aStruct is IPropertyContainer container)
                        {
                            toVisit.Push(container);
                        }
                        break;
                    }
                    }
                }
            }
        }
        private void visit(Stack <IPropertyContainer> toVisit, GameObjectContainer container, bool followReferences, bool withComponents)
        {
            while (toVisit.Any())
            {
                IPropertyContainer currentInstance = toVisit.Pop();

                if (followReferences)
                {
                    foreach (IProperty property in currentInstance.Properties)
                    {
                        if (property is PropertyObject po)
                        {
                            ObjectReference reference  = po.Value;
                            GameObject      referenced = reference.GetObject(container);
                            if (referenced != null && !MappedObjects.ContainsKey(referenced.Id))
                            {
                                MappedObjects[referenced.Id] = referenced;
                                toVisit.Push(referenced);
                            }
                        }
                        else if (property is PropertyArray pa)
                        {
                            IArkArray <IStruct>         structList          = pa.GetTypedValue <IStruct>();
                            IArkArray <ObjectReference> objectReferenceList = pa.GetTypedValue <ObjectReference>();
                            if (structList != null)
                            {
                                foreach (IStruct aStruct in structList)
                                {
                                    if (aStruct is IPropertyContainer propertyContainer)
                                    {
                                        toVisit.Push(propertyContainer);
                                    }
                                }
                            }
                            else if (objectReferenceList != null)
                            {
                                foreach (ObjectReference reference in objectReferenceList)
                                {
                                    GameObject referenced = reference.GetObject(container);
                                    if (referenced != null && !MappedObjects.ContainsKey(referenced.Id))
                                    {
                                        MappedObjects[referenced.Id] = referenced;
                                        toVisit.Push(referenced);
                                    }
                                }
                            }
                        }
                        else if (property is PropertyStruct ps)
                        {
                            IStruct aStruct = ps.Value;
                            if (aStruct is IPropertyContainer propertyContainer)
                            {
                                toVisit.Push(propertyContainer);
                            }
                        }
                    }
                }

                if (withComponents && currentInstance is GameObject)
                {
                    GameObject gameObject = (GameObject)currentInstance;

                    foreach (GameObject component in gameObject.Components.Values)
                    {
                        if (!MappedObjects.ContainsKey(component.Id))
                        {
                            MappedObjects[component.Id] = component;
                            toVisit.Push(component);
                        }
                    }
                }
            }
        }