private void AgentCachedTextureResponseHandler(Packet packet, Simulator simulator)
        {
            Client.DebugLog("AgentCachedTextureResponseHandler()");
            
            AgentCachedTextureResponsePacket response = (AgentCachedTextureResponsePacket)packet;
            Dictionary<int, float> paramValues = new Dictionary<int, float>(VisualParams.Params.Count);

            // Build a dictionary of appearance parameter indices and values from the wearables
            foreach (KeyValuePair<int,VisualParam> kvp in VisualParams.Params)
            {
                bool found = false;
                VisualParam vp = kvp.Value;

                // Try and find this value in our collection of downloaded wearables
                foreach (WearableData data in Wearables.Dictionary.Values)
                {
                    if (data.Asset.Params.ContainsKey(vp.ParamID))
                    {
                        paramValues.Add(vp.ParamID,data.Asset.Params[vp.ParamID]);
                        found = true;
                        break;
                    }
                }

                // Use a default value if we don't have one set for it
                if (!found) paramValues.Add(vp.ParamID, vp.DefaultValue);
            }

            lock (AgentTextures)
            {
                foreach (AgentCachedTextureResponsePacket.WearableDataBlock block in response.WearableData)
                {
                    // For each missing element we need to bake our own texture
                    Client.DebugLog("Cache response, index: " + block.TextureIndex + ", ID: " +
                        block.TextureID.ToString());

                    // FIXME: Use this. Right now we treat baked images on other sims as if they were missing
                    string host = Helpers.FieldToUTF8String(block.HostName);
                    if (host.Length > 0) Client.DebugLog("Cached bake exists on foreign host " + host);

                    BakeType bakeType = (BakeType)block.TextureIndex;
                    
                    // Convert the baked index to an AgentTexture index
                    if (block.TextureID != LLUUID.Zero && host.Length == 0)
                    {
                        TextureIndex index = BakeTypeToAgentTextureIndex(bakeType);
                        AgentTextures[(int)index] = block.TextureID;
                    }
                    else
                    {
                        int imageCount = 0;

                        // Download all of the images in this layer
                        switch (bakeType)
                        {
                            case BakeType.Head:
                                lock (ImageDownloads)
                                {
                                    imageCount += AddImageDownload(TextureIndex.HeadBodypaint);
                                    //imageCount += AddImageDownload(TextureIndex.Hair);
                                }
                                break;
                            case BakeType.UpperBody:
                                lock (ImageDownloads)
                                {
                                    imageCount += AddImageDownload(TextureIndex.UpperBodypaint);
                                    imageCount += AddImageDownload(TextureIndex.UpperGloves);
                                    imageCount += AddImageDownload(TextureIndex.UpperUndershirt);
                                    imageCount += AddImageDownload(TextureIndex.UpperShirt);
                                    imageCount += AddImageDownload(TextureIndex.UpperJacket);
                                }
                                break;
                            case BakeType.LowerBody:
                                lock (ImageDownloads)
                                {
                                    imageCount += AddImageDownload(TextureIndex.LowerBodypaint);
                                    imageCount += AddImageDownload(TextureIndex.LowerUnderpants);
                                    imageCount += AddImageDownload(TextureIndex.LowerSocks);
                                    imageCount += AddImageDownload(TextureIndex.LowerShoes);
                                    imageCount += AddImageDownload(TextureIndex.LowerPants);
                                    imageCount += AddImageDownload(TextureIndex.LowerJacket);
                                }
                                break;
                            case BakeType.Eyes:
                                lock (ImageDownloads)
                                {
                                    imageCount += AddImageDownload(TextureIndex.EyesIris);
                                }
                                break;
                            case BakeType.Skirt:
                                if (Wearables.ContainsKey(WearableType.Skirt))
                                {
                                    lock (ImageDownloads)
                                    {
                                        imageCount += AddImageDownload(TextureIndex.Skirt);
                                    }
                                }
                                break;
                            default:
                                Client.Log("Unknown BakeType " + block.TextureIndex, Helpers.LogLevel.Warning);
                                break;
                        }

                        if (!PendingBakes.ContainsKey(bakeType))
                        {
                            Client.DebugLog("Initializing " + bakeType.ToString() + " bake with " + imageCount + " textures");

                            if (imageCount == 0)
                            {
                                // if there are no textures to download, we can bake right away and start the upload
                                Baker bake = new Baker(Client, bakeType, 0, paramValues);
                                UploadBake(bake);
                            }
                            else
                            {
                                lock (PendingBakes)
                                    PendingBakes.Add(bakeType, new Baker(Client, bakeType, imageCount, paramValues));
                            }
                        }
                        else if (!PendingBakes.ContainsKey(bakeType))
                        {
                            Client.Log("No cached bake for " + bakeType.ToString() + " and no textures for that " +
                                "layer, this is an unhandled case", Helpers.LogLevel.Error);
                        }
                    }
                }
            }

            if (ImageDownloads.Count == 0)
            {
                // No pending downloads for baking, we're done
                CachedResponseEvent.Set();
            }
            else
            {
                lock (ImageDownloads)
                {
                    foreach (LLUUID image in ImageDownloads.Keys)
                    {
                        // Download all the images we need for baking
                        Assets.RequestImage(image, ImageType.Normal, 1013000.0f, 0);
                    }
                }
            }
        }
        private void UploadBake(Baker bake)
        {
            // Upload the completed layer data
            LLUUID transactionID = Assets.RequestUpload(bake.BakedTexture, true, true, false);

            Client.DebugLog(String.Format("Bake {0} completed. Uploading asset {1}", bake.BakeType,
                bake.BakedTexture.AssetID.ToString()));

            // Add it to a pending uploads list
            lock (PendingUploads) PendingUploads.Add(bake.BakedTexture.AssetID, BakeTypeToAgentTextureIndex(bake.BakeType));
        }