/// <summary>
        /// Assign a single material value.  Based on the values passed we'll either set (or clear) the materials for a SOP.
        /// </summary>
        /// <param name="sop">The SOP being affected.</param>
        /// <param name="face">The face to assign, or -1 if the default texture is being set.</param>
        /// <param name="id">The ID assigned to this material.  Setting a Zero UUID clears it.</param>
        /// <param name="material">If not null, the material to set.  Otherwise we are clearing.</param>
        private void AssignSingleMaterial(SceneObjectPart sop, int face, OSDMap matData)
        {
            UUID id = UUID.Zero;

            // If there is a material being set, see if we've seen it before.
            // If not we'll add it to the Shape RenderMaterials and the region cache
            if (matData != null)
            {
                RenderMaterial material = RenderMaterial.FromOSD(matData);
                id = sop.Shape.RenderMaterials.AddMaterial(material);
                m_scene.EventManager.TriggerRenderMaterialAddedToPrim(sop, id, material);

                m_log.DebugFormat("[RenderMaterials]: SOP {0}, Face {1}, Adding RenderMaterial {2}",
                                  sop.LocalId, face, material.ToString());
            }

            // If the new material is replacing one lets record it so we can clean up
            UUID oldMaterialID = UUID.Zero;

            /// Get a copy of the texture entry so we can make changes.
            var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length);

            // Set the Material ID in the TextureEntry. If face is ALL_SIDES then
            // set the default entry, otherwise fetch the face and set it there.
            if (face < 0)
            {
                oldMaterialID = te.DefaultTexture.MaterialID;
                te.DefaultTexture.MaterialID = id;
            }
            else
            {
                var faceEntry = te.CreateFace((uint)face);
                oldMaterialID        = faceEntry.MaterialID;
                faceEntry.MaterialID = id;
            }

            // Update the texture entry which will force an update to connected clients
            sop.UpdateTexture(te);

            // If the material has changed and it wasn't previously Zero
            // Deallocate the old value if its not in use and signal the change
            if ((oldMaterialID != id) &&
                (oldMaterialID != UUID.Zero))
            {
                var currentMaterialIDs = sop.Shape.GetMaterialIDs();
                if (currentMaterialIDs.Contains(oldMaterialID) == false)
                {
                    if (sop.Shape.RenderMaterials.ContainsMaterial(oldMaterialID) == true)
                    {
                        sop.Shape.RenderMaterials.RemoveMaterial(oldMaterialID);
                    }

                    m_scene.EventManager.TriggerRenderMaterialRemovedFromPrim(sop, oldMaterialID);
                }
            }
        }
            /// <summary>
            /// Called once new texture data has been received for this updater.
            /// </summary>
            public void DataReceived(byte[] data, Scene scene)
            {
                SceneObjectPart part = scene.GetSceneObjectPart(PrimID);

                if (part == null || data == null || data.Length <= 1)
                {
                    string msg =
                        String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
                    scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
                                  0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
                    return;
                }

                byte[]    assetData = null;
                AssetBase oldAsset  = null;

                if (BlendWithOldTexture)
                {
                    Primitive.TextureEntryFace defaultFace = part.Shape.Textures.DefaultTexture;
                    if (defaultFace != null)
                    {
                        oldAsset = scene.AssetService.Get(defaultFace.TextureID.ToString());

                        if (oldAsset != null)
                        {
                            assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha);
                        }
                    }
                }

                if (assetData == null)
                {
                    assetData = new byte[data.Length];
                    Array.Copy(data, assetData, data.Length);
                }

                // Create a new asset for user
                AssetBase asset = new AssetBase(UUID.Random(), "DynamicImage" + Util.RandomClass.Next(1, 10000), (sbyte)AssetType.Texture,
                                                scene.RegionInfo.RegionID.ToString());

                asset.Data        = assetData;
                asset.Description = String.Format("URL image : {0}", Url);
                asset.Local       = false;
                asset.Temporary   = ((Disp & DISP_TEMP) != 0);
                scene.AssetService.Store(asset);
//                scene.CommsManager.AssetCache.AddAsset(asset);

                IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface <IJ2KDecoder>();

                if (cacheLayerDecode != null)
                {
                    cacheLayerDecode.Decode(asset.FullID, asset.Data);
                    cacheLayerDecode = null;
                    LastAssetID      = asset.FullID;
                }

                UUID oldID = UUID.Zero;

                lock (part)
                {
                    // mostly keep the values from before
                    Primitive.TextureEntry tmptex = part.Shape.Textures;

                    // remove the old asset from the cache
                    oldID = tmptex.DefaultTexture.TextureID;

                    if (Face == ALL_SIDES)
                    {
                        tmptex.DefaultTexture.TextureID = asset.FullID;
                    }
                    else
                    {
                        try
                        {
                            Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
                            texface.TextureID         = asset.FullID;
                            tmptex.FaceTextures[Face] = texface;
                        }
                        catch (Exception)
                        {
                            tmptex.DefaultTexture.TextureID = asset.FullID;
                        }
                    }

                    // I'm pretty sure we always want to force this to true
                    // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
                    // tmptex.DefaultTexture.Fullbright = true;

                    part.UpdateTexture(tmptex);
                }

                if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
                {
                    if (oldAsset == null)
                    {
                        oldAsset = scene.AssetService.Get(oldID.ToString());
                    }
                    if (oldAsset != null)
                    {
                        if (oldAsset.Temporary == true)
                        {
                            scene.AssetService.Delete(oldID.ToString());
                        }
                    }
                }
            }