public UUID SaveBitmap (Bitmap data, bool lossless, bool temporary)
        {
            AssetBase asset = new AssetBase (
                UUID.Random (),
                "MRMDynamicImage",
                AssetType.Texture,
                m_scene.RegionInfo.RegionID) {
                Data = OpenJPEG.EncodeFromImage (data, lossless),
                Description = "MRM Image",
                Flags = (temporary) ? AssetFlags.Temporary : 0
            };

            var assetID = m_scene.AssetService.Store (asset);
            asset.Dispose ();
            return assetID;
        }
        /// <summary>
        ///     Load an asset
        /// </summary>
        /// <param name="assetPath"> </param>
        /// <param name="data"></param>
        /// <returns>true if asset was successfully loaded, false otherwise</returns>
        bool LoadAsset (string assetPath, byte [] data)
        {
            //IRegionSerialiser serialiser = scene.RequestModuleInterface<IRegionSerialiser>();
            // Right now we're nastily obtaining the UUID from the filename
            string filename = assetPath.Remove (0, ArchiveConstants.ASSETS_PATH.Length);

            int i = filename.LastIndexOf (ArchiveConstants.ASSET_EXTENSION_SEPARATOR, StringComparison.Ordinal);

            if (i == -1) {
                MainConsole.Instance.ErrorFormat (
                    "[Inventory Archiver]: Could not find extension information in asset path {0} since it's missing the separator {1}.  Skipping",
                    assetPath, ArchiveConstants.ASSET_EXTENSION_SEPARATOR);

                return false;
            }

            string extension = filename.Substring (i);
            string uuid = filename.Remove (filename.Length - extension.Length);
            UUID assetID = UUID.Parse (uuid);

            if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey (extension)) {
                AssetType assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE [extension];

                if (assetType == AssetType.Unknown)
                    MainConsole.Instance.WarnFormat (
                        "[Inventory Archiver]: Importing {0} byte asset {1} with unknown type", data.Length,
                        uuid);
                else if (assetType == AssetType.Object) {
                    string xmlData = Utils.BytesToString (data);
                    ISceneEntity sceneObject = SceneEntitySerializer.SceneObjectSerializer.FromOriginalXmlFormat (
                        xmlData, m_registry);
                    if (sceneObject != null) {
                        if (m_creatorIdForAssetId.ContainsKey (assetID)) {
                            foreach (
                                ISceneChildEntity sop in
                                    from sop in sceneObject.ChildrenEntities ()
                                    where string.IsNullOrEmpty (sop.CreatorData)
                                    select sop)
                                sop.CreatorID = m_creatorIdForAssetId [assetID];
                        }

                        foreach (ISceneChildEntity sop in sceneObject.ChildrenEntities ()) {
                            //Fix ownerIDs and perms
                            sop.Inventory.ApplyGodPermissions ((uint)PermissionMask.All);
                            sceneObject.ApplyPermissions ((uint)PermissionMask.All);
                            foreach (TaskInventoryItem item in sop.Inventory.GetInventoryItems ())
                                item.OwnerID = m_userInfo.PrincipalID;
                            sop.OwnerID = m_userInfo.PrincipalID;
                        }

                        data =
                            Utils.StringToBytes (
                                SceneEntitySerializer.SceneObjectSerializer.ToOriginalXmlFormat (sceneObject));
                    }
                }
                //MainConsole.Instance.DebugFormat("[Inventory Archiver]: Importing asset {0}, type {1}", uuid, assetType);

                AssetBase asset = new AssetBase (assetID, m_invName, assetType, m_overridecreator) {
                    Data = data,
                    Flags = AssetFlags.Normal
                };

                if (m_assetData != null && ReplaceAssets)
                    m_assetData.Delete (asset.ID, true);

                // check if this asset already exists in the database
                try {
                    if (!m_assetService.GetExists (asset.ID.ToString ()))
                        m_assetService.Store (asset);
                } catch {
                    MainConsole.Instance.Error (
                        "[Inventory Archiver]: Error checking if asset exists. Possibly 'Path too long' for file based asset storage");
                }
                asset.Dispose ();
                return true;
            }
            MainConsole.Instance.ErrorFormat (
                "[Inventory Archiver]: Tried to dearchive data with path {0} with an unknown type extension {1}",
                assetPath, extension);

            return false;
        }
        /// <summary>
        /// </summary>
        /// <param name="httpRequest"></param>
        /// <param name="httpResponse"></param>
        /// <param name="textureID"></param>
        /// <param name="format"></param>
        /// <param name="response"></param>
        /// <returns>False for "caller try another codec"; true otherwise</returns>
        bool FetchTexture (OSHttpRequest httpRequest, OSHttpResponse httpResponse, UUID textureID, string format,
                                  out byte [] response)
        {
            //MainConsole.Instance.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
            AssetBase texture;

            string fullID = textureID.ToString ();
            if (format != DefaultFormat)
                fullID = fullID + "-" + format;

            if (!string.IsNullOrEmpty (REDIRECT_URL)) {
                // Only try to fetch locally cached textures. Misses are redirected
                texture = m_assetService.GetCached (fullID);

                if (texture != null) {
                    if (texture.Type != (sbyte)AssetType.Texture &&        // not actually a texture
                        texture.Type != (sbyte)AssetType.Unknown &&        // .. but valid
                        texture.Type != (sbyte)AssetType.Simstate) {
                        httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                        response = MainServer.BlankResponse;
                        return true;
                    }

                    response = WriteTextureData (httpRequest, httpResponse, texture, format);
                    return true;
                } else {
                    string textureUrl = REDIRECT_URL + textureID;
                    MainConsole.Instance.Debug ("[AssetCAPS]: Redirecting texture request to " + textureUrl);
                    httpResponse.RedirectLocation = textureUrl;
                    response = MainServer.BlankResponse;
                    return true;
                }
            }

            // no redirect
            // try the cache
            texture = m_assetService.GetCached (fullID);

            if (texture == null) {
                //MainConsole.Instance.DebugFormat("[GETTEXTURE]: texture was not in the cache");

                // Fetch locally or remotely. Misses return a 404
                texture = m_assetService.Get (textureID.ToString ());

                if (texture != null) {
                    if (texture.Type != (sbyte)AssetType.Texture &&
                        texture.Type != (sbyte)AssetType.Unknown &&
                        texture.Type != (sbyte)AssetType.Simstate) {
                        httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                        response = MainServer.BlankResponse;
                        texture.Dispose ();
                        return true;
                    }

                    if (format == DefaultFormat) {
                        try {
                            response = WriteTextureData (httpRequest, httpResponse, texture, format);
                        } catch {
                            response = MainServer.BlankResponse;
                        }
                        texture.Dispose ();
                        return true;
                    }

                    AssetBase newTexture = new AssetBase (texture.ID + "-" + format, texture.Name, AssetType.Texture,
                                                                     texture.CreatorID) { Data = ConvertTextureData (texture, format) };

                    if (newTexture.Data.Length == 0)            // unable to convert
                    {
                        response = MainServer.BlankResponse;
                        texture.Dispose ();
                        newTexture.Dispose ();
                        return false; // !!! Caller try another codec, please!
                    }

                    newTexture.Flags = AssetFlags.Collectable | AssetFlags.Temporary;
                    newTexture.ID = m_assetService.Store (newTexture);
                    try {
                        response = WriteTextureData (httpRequest, httpResponse, newTexture, format);
                    } catch {
                        response = MainServer.BlankResponse;
                    }
                    newTexture.Dispose ();
                    texture.Dispose ();

                    return true;
                }

                // nothing found... replace with the 'missing_texture" texture
                // try the cache first
                texture = m_assetService.GetCached (Constants.MISSING_TEXTURE_ID);

                if (texture == null)
                    texture = m_assetService.Get (Constants.MISSING_TEXTURE_ID);		// not in local cache...

                if (texture != null) {
                    if (format == DefaultFormat) {
                        MainConsole.Instance.Debug ("[AssetCAPS]: Texture " + textureID + " replaced with default 'missing' texture");
                        response = WriteTextureData (httpRequest, httpResponse, texture, format);
                        texture.Dispose ();
                        return true;
                    }
                }

                // texture not found and we have no 'missing texture'??
                // ... or if all else fails...
                MainConsole.Instance.Warn ("[AssetCAPS]: Texture " + textureID + " not found (no default)");
                httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                response = MainServer.BlankResponse;
                return true;

            }

            // found the texture in the cache
            if (texture.Type != (sbyte)AssetType.Texture &&
                texture.Type != (sbyte)AssetType.Unknown &&
                texture.Type != (sbyte)AssetType.Simstate) {
                httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                response = MainServer.BlankResponse;
                return true;
            }

            // the best result...
            //MainConsole.Instance.DebugFormat("[GETTEXTURE]: texture was in the cache");
            response = WriteTextureData (httpRequest, httpResponse, texture, format);
            return true;

        }
        /// <summary>
        ///     Create a new 'link' to another inventory item
        ///     Used in Viewer 2 for appearance.
        /// </summary>
        /// <param name="remoteClient"></param>
        /// <param name="transActionID"></param>
        /// <param name="folderID"></param>
        /// <param name="callbackID"></param>
        /// <param name="description"></param>
        /// <param name="name"></param>
        /// <param name="invType"></param>
        /// <param name="type"></param>
        /// <param name="olditemID"></param>
        protected void HandleLinkInventoryItem(IClientAPI remoteClient, UUID transActionID, UUID folderID,
                                               uint callbackID, string description, string name,
                                               sbyte invType, sbyte type, UUID olditemID)
        {
            //MainConsole.Instance.DebugFormat("[Agent inventory]: Received request to create inventory item link {0} in folder {1} pointing to {2}", name, folderID, olditemID);

            if (!m_scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
                return;

            IScenePresence presence;
            if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
            {
                if (olditemID == AvatarWearable.DEFAULT_EYES_ITEM ||
                    olditemID == AvatarWearable.DEFAULT_SHAPE_ITEM ||
                    olditemID == AvatarWearable.DEFAULT_HAIR_ITEM ||
                    olditemID == AvatarWearable.DEFAULT_PANTS_ITEM ||
                    olditemID == AvatarWearable.DEFAULT_SHIRT_ITEM ||
                    olditemID == AvatarWearable.DEFAULT_SKIN_ITEM)
                {
                    return;
                }
                AssetBase asset = new AssetBase {ID = olditemID, Type = type, Name = name, Description = description};
                try {
                    CreateNewInventoryItem (
                        remoteClient, remoteClient.AgentId.ToString (), "", folderID, name, 0, callbackID, asset, invType,
                        (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All,
                        (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch ());
                } catch {
                }
                asset.Dispose ();
            }
            else
            {
                MainConsole.Instance.ErrorFormat(
                    "ScenePresence for agent uuid {0} unexpectedly not found in HandleLinkInventoryItem",
                    remoteClient.AgentId);
            }
        }