/// <summary>
        ///     Gather all the asset uuids associated with a given object.
        /// </summary>
        /// This includes both those directly associated with
        /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
        /// within this object).
        /// <param name="sceneObject">The scene object for which to gather assets</param>
        /// <param name="assetUuids">The assets gathered</param>
        public void GatherAssetUuids(ISceneEntity sceneObject, IDictionary <UUID, AssetType> assetUuids)
        {
            //MainConsole.Instance.DebugFormat(
            //    "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);

            ISceneChildEntity [] parts = sceneObject.ChildrenEntities().ToArray();
            foreach (ISceneChildEntity part in parts)
            {
                //MainConsole.Instance.DebugFormat(
                //    "[Archiver]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);

                try {
                    Primitive.TextureEntry textureEntry = part.Shape.Textures;
                    if (textureEntry != null)
                    {
                        // Get the prim's default texture.  This will be used for faces which don't have their own texture
                        if (textureEntry.DefaultTexture != null)
                        {
                            assetUuids [textureEntry.DefaultTexture.TextureID] = AssetType.Texture;
                        }

                        if (textureEntry.FaceTextures != null)
                        {
                            // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture)
                            foreach (
                                Primitive.TextureEntryFace texture in
                                textureEntry.FaceTextures.Where(texture => texture != null))
                            {
                                assetUuids [texture.TextureID] = AssetType.Texture;
                            }
                        }
                    }

                    // If the prim is a sculpt then preserve this information too
                    if (part.Shape.SculptTexture != UUID.Zero)
                    {
                        assetUuids [part.Shape.SculptTexture] = AssetType.Texture;
                    }

                    TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();

                    // Now analyze this prim's inventory items to preserve all the uuids that they reference
                    foreach (
                        TaskInventoryItem tii in
                        taskDictionary.Values.Where(tii => !assetUuids.ContainsKey(tii.AssetID)))
                    {
                        if (!assetUuids.ContainsKey(tii.AssetID))
                        {
                            GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids);
                        }
                    }
                    GatherMaterialsUuids(part, assetUuids);
                } catch (Exception e) {
                    MainConsole.Instance.ErrorFormat("[UUID Gatherer]: Failed to get part - {0}", e);
                    MainConsole.Instance.DebugFormat(
                        "[UUID Gatherer]: Texture entry length for prim was {0} (min is 46)",
                        part.Shape.TextureEntry.Length);
                }
            }
        }
        public object Clone()
        {
            var clone = new TaskInventoryDictionary();

            lock (this) {
                foreach (UUID uuid in Keys)
                {
                    clone.Add(uuid, (TaskInventoryItem)this [uuid].Clone());
                }
            }

            return(clone);
        }