/// <summary>
        ///     Create the calling card inventory item in the user's inventory
        /// </summary>
        /// <param name="client"></param>
        /// <param name="creator"></param>
        /// <param name="folder"></param>
        /// <param name="name"></param>
        public void CreateCallingCard(IClientAPI client, UUID creator, UUID folder, string name)
        {
            MainConsole.Instance.Debug("[Universe CALLING CARD MODULE]: Creating calling card for " + client.Name);
            InventoryItemBase item = new InventoryItemBase
            {
                AssetID             = UUID.Zero,
                AssetType           = (int)AssetType.CallingCard,
                BasePermissions     = (uint)(PermissionMask.Copy | PermissionMask.Modify),
                CurrentPermissions  = (uint)(PermissionMask.Copy | PermissionMask.Modify),
                NextPermissions     = (uint)PermissionMask.None,
                CreationDate        = Util.UnixTimeSinceEpoch(),
                CreatorId           = creator.ToString(),
                Description         = "",
                EveryOnePermissions = (uint)PermissionMask.None,
                Flags      = 0,
                Folder     = folder,
                GroupID    = UUID.Zero,
                GroupOwned = false,
                ID         = UUID.Random(),
                InvType    = (int)InventoryType.CallingCard,
                Name       = name,
                Owner      = client.AgentId,
                SalePrice  = 10,
                SaleType   = (byte)SaleType.Not
            };


            ILLClientInventory inventory = client.Scene.RequestModuleInterface <ILLClientInventory>();

            if (inventory != null)
            {
                inventory.AddInventoryItemAsync(client, item);
            }
        }
        private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
        {
            //MainConsole.Instance.InfoFormat("[INVENTORY TRANSFER]: OnInstantMessage {0}", im.dialog);
            IScene clientScene = FindClientScene(client.AgentId);

            if (clientScene == null) // Something seriously wrong here.
            {
                MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Cannot find originating user scene");
                return;
            }

            if (im.Dialog == (byte)InstantMessageDialog.InventoryOffered)
            {
                //MainConsole.Instance.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0]));

                if (im.BinaryBucket.Length < 17) // Invalid
                {
                    MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Invalid length {0} for asset type {1}",
                                                     im.BinaryBucket.Length, ((AssetType)im.BinaryBucket[0]));
                    return;
                }

                UUID           receipientID       = im.ToAgentID;
                IScenePresence recipientUser      = null;
                IScene         recipientUserScene = FindClientScene(client.AgentId);
                if (recipientUserScene != null)
                {
                    recipientUser = recipientUserScene.GetScenePresence(receipientID);
                }
                UUID copyID;

                // user is online now...
                if (recipientUser != null)
                {
                    // First byte is the asset type
                    AssetType assetType = (AssetType)im.BinaryBucket [0];

                    if (assetType == AssetType.Folder)
                    {
                        UUID folderID = new UUID(im.BinaryBucket, 1);

                        MainConsole.Instance.DebugFormat(
                            "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory",
                            folderID, im.ToAgentID);


                        clientScene.InventoryService.GiveInventoryFolderAsync(
                            receipientID,
                            client.AgentId,
                            folderID,
                            UUID.Zero,
                            (folder) =>
                        {
                            if (folder == null)
                            {
                                client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false);
                                return;
                            }

                            // The outgoing binary bucket should contain only the byte which signals an asset folder is
                            // being copied and the following bytes for the copied folder's UUID
                            copyID              = folder.ID;
                            byte[] copyIDBytes  = copyID.GetBytes();
                            im.BinaryBucket     = new byte[1 + copyIDBytes.Length];
                            im.BinaryBucket [0] = (byte)AssetType.Folder;
                            Array.Copy(copyIDBytes, 0, im.BinaryBucket, 1, copyIDBytes.Length);

//                                m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0,
//                                    "Inworld inventory folder transfer", TransactionType.GiveInventory, UUID.Zero);
                            if (moneyService != null)
                            {
                                moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                                      "Inworld inventory folder transfer", TransactionType.GiveInventory);
                            }

                            if (recipientUser != null)
                            {
                                recipientUser.ControllingClient.SendBulkUpdateInventory(folder);
                                im.SessionID = copyID;
                                recipientUser.ControllingClient.SendInstantMessage(im);
                            }
                        });
                    }
                    else
                    {
                        // First byte of the array is probably the item type
                        // Next 16 bytes are the UUID

                        UUID itemID = new UUID(im.BinaryBucket, 1);

                        MainConsole.Instance.DebugFormat(
                            "[INVENTORY TRANSFER]: (giving) Inserting item {0} into agent {1}'s inventory",
                            itemID, im.ToAgentID);

                        clientScene.InventoryService.GiveInventoryItemAsync(
                            im.ToAgentID,
                            im.FromAgentID,
                            itemID,
                            UUID.Zero,
                            false,
                            (itemCopy) =>
                        {
                            if (itemCopy == null)
                            {
                                MainConsole.Instance.DebugFormat(
                                    "[INVENTORY TRANSFER]: (giving) Unable to find item {0} to give to agent {1}'s inventory",
                                    itemID, im.ToAgentID);
                                client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
                                return;
                            }

                            copyID = itemCopy.ID;
                            Array.Copy(copyID.GetBytes(), 0, im.BinaryBucket, 1, 16);

                            if (moneyService != null)
                            {
                                moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                                      "Inworld inventory item transfer", TransactionType.GiveInventory);
                            }

                            if (recipientUser != null)
                            {
                                recipientUser.ControllingClient.SendBulkUpdateInventory(itemCopy);
                                im.SessionID = itemCopy.ID;
                                recipientUser.ControllingClient.SendInstantMessage(im);
                            }
                        });
                    }
                }
                else
                {
                    // recipient is offline.
                    // Send the IM to the recipient. The item is already
                    // in their inventory, so it will not be lost if
                    // they are offline.
                    //
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im);
                    }
                }
            }
            else if (im.Dialog == (byte)InstantMessageDialog.InventoryAccepted)
            {
                IScenePresence user = clientScene.GetScenePresence(im.ToAgentID);
                MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Acceptance message received");

                if (user != null) // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im);
                    }
                }
            }
            else if (im.Dialog == (byte)InstantMessageDialog.InventoryDeclined)
            {
                // Here, the recipient is local and we can assume that the
                // inventory is loaded. Courtesy of the above bulk update,
                // It will have been pushed to the client, too
                //
                IInventoryService invService = clientScene.InventoryService;
                MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Declined message received");

                InventoryFolderBase trashFolder =
                    invService.GetFolderForType(client.AgentId, InventoryType.Unknown, AssetType.TrashFolder);

                UUID inventoryID = im.SessionID; // The inventory item/folder, back from it's trip

                InventoryItemBase   item   = invService.GetItem(client.AgentId, inventoryID);
                InventoryFolderBase folder = null;

                if (item != null && trashFolder != null)
                {
                    item.Folder = trashFolder.ID;

                    // Diva comment: can't we just update this item???
                    List <UUID> uuids = new List <UUID> {
                        item.ID
                    };
                    invService.DeleteItems(item.Owner, uuids);
                    ILLClientInventory inventory = client.Scene.RequestModuleInterface <ILLClientInventory>();
                    if (inventory != null)
                    {
                        inventory.AddInventoryItemAsync(client, item);
                    }
                }
                else
                {
                    folder = new InventoryFolderBase(inventoryID, client.AgentId);
                    folder = invService.GetFolder(folder);

                    if (folder != null & trashFolder != null)
                    {
                        folder.ParentID = trashFolder.ID;
                        invService.MoveFolder(folder);
                        client.SendBulkUpdateInventory(folder);
                    }
                }

                if ((null == item && null == folder) | null == trashFolder)
                {
                    string reason = String.Empty;

                    if (trashFolder == null)
                    {
                        reason += " Trash folder not found.";
                    }
                    if (item == null)
                    {
                        reason += " Item not found.";
                    }
                    if (folder == null)
                    {
                        reason += " Folder not found.";
                    }

                    client.SendAgentAlertMessage("Unable to delete " +
                                                 "received inventory" + reason, false);
                }

                //m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0,
                //    "Inworld inventory transfer declined", TransactionType.GiveInventory, UUID.Zero);
                if (moneyService != null)
                {
                    moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                          "Inworld inventory transfer declined", TransactionType.GiveInventory);
                }

                IScenePresence user = clientScene.GetScenePresence(im.ToAgentID);

                if (user != null) // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im);
                    }
                }
            }
        }