/// <summary>
        /// Respond to the cached textures request from the client
        /// </summary>
        /// <param name="client"></param>
        /// <param name="serial"></param>
        /// <param name="cachedTextureRequest"></param>
        private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest)
        {
            // m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId);
            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);

            List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>();
            foreach (CachedTextureRequestArg request in cachedTextureRequest)
            {
                UUID texture = UUID.Zero;
                int index = request.BakedTextureIndex;
                
                if (m_reusetextures)
                {
                    // this is the most insanely dumb way to do this... however it seems to
                    // actually work. if the appearance has been reset because wearables have
                    // changed then the texture entries are zero'd out until the bakes are 
                    // uploaded. on login, if the textures exist in the cache (eg if you logged
                    // into the simulator recently, then the appearance will pull those and send
                    // them back in the packet and you won't have to rebake. if the textures aren't
                    // in the cache then the intial makeroot() call in scenepresence will zero
                    // them out.
                    //
                    // a better solution (though how much better is an open question) is to
                    // store the hashes in the appearance and compare them. Thats's coming.

                    Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index];
                    if (face != null)
                        texture = face.TextureID;

                    // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index);
                }
                
                CachedTextureResponseArg response = new CachedTextureResponseArg();
                response.BakedTextureIndex = index;
                response.BakedTextureID = texture;
                response.HostName = null;

                cachedTextureResponse.Add(response);
            }
            
            // m_log.WarnFormat("[AVFACTORY]: serial is {0}",serial);
            // The serial number appears to be used to match requests and responses
            // in the texture transaction. We just send back the serial number
            // that was provided in the request. The viewer bumps this for us.
            client.SendCachedTextureResponse(sp, serial, cachedTextureResponse);
        }
        /// <summary>
        /// Respond to the cached textures request from the client
        /// </summary>
        /// <param name="client"></param>
        /// <param name="serial"></param>
        /// <param name="cachedTextureRequest"></param>
        private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest)
        {
            if (m_log.IsDebugEnabled) {
                m_log.DebugFormat ("{0} called", System.Reflection.MethodBase.GetCurrentMethod ().Name);
            }

            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);

            List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>();
            foreach (CachedTextureRequestArg request in cachedTextureRequest)
            {
                UUID texture = UUID.Zero;
                int index = request.BakedTextureIndex;
                
                if (m_reusetextures)
                {
                    if (sp.Appearance.GetTextureHash(index) == request.WearableHashID)
                    {
                        Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index];
                        if (face != null)
                            texture = face.TextureID;
                    }
                    else
                    {
                        // We know that that hash is wrong, null it out
                        // and wait for the setappearance call
                        sp.Appearance.SetTextureHash(index,UUID.Zero);
                    }

                    // m_log.WarnFormat("[AVFACTORY]: use texture {0} for index {1}; hash={2}",texture,index,request.WearableHashID);
                }
                
                CachedTextureResponseArg response = new CachedTextureResponseArg();
                response.BakedTextureIndex = index;
                response.BakedTextureID = texture;
                response.HostName = null;

                cachedTextureResponse.Add(response);
            }
            
            // m_log.WarnFormat("[AVFACTORY]: serial is {0}",serial);
            // The serial number appears to be used to match requests and responses
            // in the texture transaction. We just send back the serial number
            // that was provided in the request. The viewer bumps this for us.
            client.SendCachedTextureResponse(sp, serial, cachedTextureResponse);
        }