/// <summary>
        /// Set appearance data (textureentry and slider settings) received from the client
        /// </summary>
        /// <param name="texture"></param>
        /// <param name="visualParam"></param>
        public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
        {
            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);

            if (sp == null)
            {
                m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
                return;
            }

//            m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId);

            // TODO: This is probably not necessary any longer, just assume the
            // textureEntry set implies that the appearance transaction is complete
            bool changed = false;

            // Process the texture entry transactionally, this doesn't guarantee that Appearance is
            // going to be handled correctly but it does serialize the updates to the appearance
            lock (m_setAppearanceLock)
            {
                // Process the visual params, this may change height as well
                if (visualParams != null)
                {
                    changed = sp.Appearance.SetVisualParams(visualParams);
                    if (sp.Appearance.AvatarHeight > 0)
                    {
                        sp.SetHeight(sp.Appearance.AvatarHeight);
                    }
                }

                // Process the baked texture array
                if (textureEntry != null)
                {
                    changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;

                    m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId);
                    Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client, false); });

                    // This appears to be set only in the final stage of the appearance
                    // update transaction. In theory, we should be able to do an immediate
                    // appearance send and save here.

                    // save only if there were changes, send no matter what (doesn't hurt to send twice)
                    if (changed)
                    {
                        QueueAppearanceSave(client.AgentId);
                    }
                    QueueAppearanceSend(client.AgentId);
                }
            }

            // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
        }
        /// <summary>
        /// Set appearance data (textureentry and slider settings) received from the client
        /// </summary>
        /// <param name="texture"></param>
        /// <param name="visualParam"></param>
        public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
        {
//            m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance for {0}",client.AgentId);

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

            if (sp == null)
            {
                m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}", client.AgentId);
                return;
            }

            bool changed = false;

            // Process the texture entry
            if (textureEntry != null)
            {
                changed = sp.Appearance.SetTextureEntries(textureEntry);

                for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
                {
                    int idx = AvatarAppearance.BAKE_INDICES[i];
                    Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
                    if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
                    {
                        Util.FireAndForget(delegate(object o) {
                            if (!CheckBakedTextureAsset(client, face.TextureID, idx))
                            {
                                client.SendRebakeAvatarTextures(face.TextureID);
                            }
                        });
                    }
                }
            }

            // Process the visual params, this may change height as well
            if (visualParams != null)
            {
                if (sp.Appearance.SetVisualParams(visualParams))
                {
                    changed = true;
                    if (sp.Appearance.AvatarHeight > 0)
                    {
                        sp.SetHeight(sp.Appearance.AvatarHeight);
                    }
                }
            }

            // If something changed in the appearance then queue an appearance save
            if (changed)
            {
                QueueAppearanceSave(client.AgentId);
            }

            // And always queue up an appearance update to send out
            QueueAppearanceSend(client.AgentId);

            // Send the appearance back to the avatar
            // AvatarAppearance avp = sp.Appearance;
            // sp.ControllingClient.SendAvatarDataImmediate(sp);
            // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
        }