public string Store(AssetBase asset)
        {
            if (asset.Temporary || asset.Local)
            {
                if (m_Cache != null)
                    m_Cache.Cache(asset);
                else
                    m_log.Warn("[CABLE BEACH ASSETS]: Cache is missing. A valid cache must be configured for proper operation");

                return asset.ID;
            }

            if (m_WorldServiceConnector != null)
            {
                // Cache the asset first
                if (m_Cache != null)
                    m_Cache.Cache(asset);

                // FIXME: OpenSim API needs to be fixed to pass this in wherever possible
                UUID userID = UUID.Zero;

                Uri createAssetUri = GetServiceCapability(userID, CableBeachServices.ASSET_CREATE_ASSET);
                if (createAssetUri != null)
                {
                    UUID assetID;
                    UUID.TryParse(asset.Metadata.ID, out assetID);

                    CreateAssetMessage create = new CreateAssetMessage();
                    create.Metadata = new MetadataDefault();

                    // Convert the OpenSim Type enum to a content-type if it is set, or try to use the OpenSim ContentType field
                    sbyte assetType = asset.Metadata.Type;
                    if (assetType != -1)
                    {
                        create.Metadata.ContentType = CableBeachUtils.SLAssetTypeToContentType(assetType);
                    }
                    else if (!String.IsNullOrEmpty(asset.Metadata.ContentType))
                    {
                        create.Metadata.ContentType = asset.Metadata.ContentType;
                    }
                    else
                    {
                        m_log.Warn("[CABLE BEACH ASSETS]: Storing asset " + assetID + " with a content-type of application/octet-stream");
                        create.Metadata.ContentType = "application/octet-stream";
                    }

                    create.Metadata.CreationDate = DateTime.Now;
                    create.Metadata.Description = asset.Metadata.Description;
                    create.Metadata.ID = assetID;
                    create.Metadata.Methods = new Dictionary<string, Uri>();
                    create.Metadata.Name = asset.Metadata.Name;
                    create.Metadata.SHA256 = OpenMetaverse.Utils.EmptyBytes;
                    create.Metadata.Temporary = asset.Metadata.Temporary;
                    create.Base64Data = Convert.ToBase64String(asset.Data);

                    CapsClient request = new CapsClient(createAssetUri);
                    OSDMap response = request.GetResponse(create.Serialize(), OSDFormat.Json, REQUEST_TIMEOUT) as OSDMap;

                    if (response != null)
                    {
                        // Parse the response
                        CreateAssetReplyMessage reply = new CreateAssetReplyMessage();
                        reply.Deserialize(response);

                        if (reply.AssetID != UUID.Zero)
                        {
                            asset.FullID = reply.AssetID;
                            asset.ID = reply.AssetID.ToString();
                            return asset.ID;
                        }
                    }
                    else
                    {
                        m_log.Error("[CABLE BEACH ASSETS]: Failed to store asset at " + createAssetUri);
                    }
                }
                else
                {
                    m_log.Warn("[CABLE BEACH ASSETS]: Failed to store remote asset " + asset.ID + ", could not find a create_asset capability");
                }
            }
            else
            {
                m_log.Error("[CABLE BEACH ASSETS]: Cannot upload asset, no reference to a world server connector");
            }

            return String.Empty;
        }
        public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            CreateAssetReplyMessage reply = new CreateAssetReplyMessage();
            reply.AssetID = UUID.Zero;
            reply.AssetUri = null;

            try
            {
                OSD osdata = OSDParser.DeserializeJson(httpRequest.InputStream);

                if (osdata.Type == OSDType.Map)
                {
                    CreateAssetMessage message = new CreateAssetMessage();
                    message.Deserialize((OSDMap)osdata);

                    byte[] assetData = null;
                    try { assetData = Convert.FromBase64String(message.Base64Data); }
                    catch (Exception) { }

                    if (assetData != null && assetData.Length > 0)
                    {
                        AssetBase asset = new AssetBase(
                            (message.Metadata.ID != UUID.Zero) ? message.Metadata.ID : UUID.Random(),
                            message.Metadata.Name,
                            CableBeachUtils.ContentTypeToSLAssetType(message.Metadata.ContentType)
                        );
                        asset.Data = assetData;
                        asset.Metadata.ContentType = message.Metadata.ContentType;
                        asset.Metadata.CreationDate = DateTime.Now;
                        asset.Metadata.Description = message.Metadata.Description;
                        asset.Metadata.ID = asset.Metadata.FullID.ToString();
                        asset.Metadata.Local = false;
                        asset.Metadata.SHA1 = OpenMetaverse.Utils.EmptyBytes; // TODO: Calculate the SHA-1 hash of the asset here?
                        asset.Metadata.Temporary = message.Metadata.Temporary;

                        string assetID = m_AssetService.Store(asset);

                        if (!String.IsNullOrEmpty(assetID))
                        {
                            reply.AssetID = message.Metadata.ID;
                            httpResponse.StatusCode = (int)HttpStatusCode.Created;
                        }
                        else
                        {
                            httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError;
                        }
                    }
                    else
                    {
                        httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
                    }
                }
            }
            catch (Exception)
            {
                httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError;
            }

            httpResponse.ContentType = "application/json";
            httpResponse.ContentEncoding = Encoding.UTF8;
            return Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(reply.Serialize()));
        }