public bool AddOfflineMessage(GridInstantMessage message)
        {
            object remoteValue = DoRemote(message);
            if (remoteValue != null || m_doRemoteOnly)
                return remoteValue == null ? false : (bool) remoteValue;

            if (m_maxOfflineMessages <= 0 ||
                GenericUtils.GetGenericCount(message.ToAgentID, "OfflineMessages", GD) < m_maxOfflineMessages)
            {
                GenericUtils.AddGeneric(message.ToAgentID, "OfflineMessages", UUID.Random().ToString(),
                                        message.ToOSD(), GD);
                return true;
            }
            return false;
        }
        public void SendChatToSession(UUID agentID, GridInstantMessage im)
        {
            if (m_doRemoteOnly)
            {
                DoRemoteCallPost(true, "InstantMessageServerURI", agentID, im);
                return;
            }

            Util.FireAndForget((o) =>
                                   {
                                       ChatSession session;
                                       ChatSessions.TryGetValue(im.SessionID, out session);
                                       if (session == null)
                                           return;

                                       if (agentID != UUID.Zero) //Not system
                                       {
                                           ChatSessionMember sender = FindMember(im.SessionID, agentID);
                                           if (sender.MuteText)
                                               return; //They have been admin muted, don't allow them to send anything
                                       }

                                       Dictionary<string, List<GridInstantMessage>> messagesToSend =
                                           new Dictionary<string, List<GridInstantMessage>>();
                                       foreach (ChatSessionMember member in session.Members)
                                       {
                                           if (member.HasBeenAdded)
                                           {
                                               im.ToAgentID = member.AvatarKey;
                                               im.BinaryBucket = Utils.StringToBytes(session.Name);
                                               im.RegionID = UUID.Zero;
                                               im.ParentEstateID = 0;
                                               im.Offline = 0;
                                               GridInstantMessage message = new GridInstantMessage();
                                               message.FromOSD(im.ToOSD());
                                               //im.timestamp = 0;
                                               string uri = FindRegionURI(member.AvatarKey);
                                               if (uri != "") //Check if they are online
                                               {
                                                   //Bulk send all of the instant messages to the same region, so that we don't send them one-by-one over and over
                                                   if (messagesToSend.ContainsKey(uri))
                                                       messagesToSend[uri].Add(message);
                                                   else
                                                       messagesToSend.Add(uri, new List<GridInstantMessage>() {message});
                                               }
                                           }
                                           else if (!member.RequestedRemoval)
                                               //If they're requested to leave, don't recontact them
                                           {
                                               UUID regionID = FindRegionID(member.AvatarKey);
                                               if (regionID != UUID.Zero)
                                               {
                                                   im.ToAgentID = member.AvatarKey;
                                                   m_eventQueueService.ChatterboxInvitation(
                                                       session.SessionID
                                                       , session.Name
                                                       , im.FromAgentID
                                                       , im.Message
                                                       , im.ToAgentID
                                                       , im.FromAgentName
                                                       , im.Dialog
                                                       , im.Timestamp
                                                       , im.Offline == 1
                                                       , (int) im.ParentEstateID
                                                       , im.Position
                                                       , 1
                                                       , im.SessionID
                                                       , false
                                                       , Utils.StringToBytes(session.Name)
                                                       , regionID
                                                       );
                                               }
                                           }
                                       }
                                       foreach (KeyValuePair<string, List<GridInstantMessage>> kvp in messagesToSend)
                                       {
                                           SendInstantMessages(kvp.Key, kvp.Value);
                                       }
                                   });
        }
        public static OSDMap FriendshipOffered(UUID requester, UUID friend, GridInstantMessage im,
            UUID requestingRegion)
        {
            OSDMap llsdBody = new OSDMap
                                  {
                                      {"Requester", requester},
                                      {"Friend", friend},
                                      {"IM", im.ToOSD()},
                                      {"RequestingRegion", requestingRegion}
                                  };

            return buildEvent("FriendshipOffered", llsdBody, requester, requestingRegion);
        }