Inheritance: Universe.Framework.Modules.IDataTransferable
        public bool AddClassified(Classified classified)
        {
            object remoteValue = DoRemote(classified);
            if (remoteValue != null || m_doRemoteOnly)
                return remoteValue != null && (bool) remoteValue;

            if (GetUserProfile(classified.CreatorUUID) == null)
                return false;
            string keywords = classified.Description;
            if (keywords.Length > 512)
                keywords = keywords.Substring(keywords.Length - 512, 512);
            //It might be updating, delete the old
            QueryFilter filter = new QueryFilter();
            filter.andFilters["ClassifiedUUID"] = classified.ClassifiedUUID;
            GD.Delete(m_userClassifiedsTable, filter);
            List<object> values = new List<object>
                                      {
                                          classified.Name,
                                          classified.Category,
                                          classified.SimName,
                                          classified.CreatorUUID,
                                          classified.ScopeID,
                                          classified.ClassifiedUUID,
                                          OSDParser.SerializeJsonString(classified.ToOSD()),
                                          classified.PriceForListing,
                                          keywords
                                      };
            return GD.Insert(m_userClassifiedsTable, values.ToArray());
        }
        public void ClassifiedInfoUpdate (UUID queryClassifiedID, uint queryCategory, string queryName,
                                         string queryDescription, UUID queryParcelID,
                                         uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos,
                                         byte queryclassifiedFlags,
                                         int queryclassifiedPrice, IClientAPI remoteClient)
        {
            IScenePresence p = remoteClient.Scene.GetScenePresence (remoteClient.AgentId);

            if (p == null)
                return; //Just fail

            IScheduledMoneyModule scheduledMoneyModule = p.Scene.RequestModuleInterface<IScheduledMoneyModule> ();
            IMoneyModule moneyModule = p.Scene.RequestModuleInterface<IMoneyModule> ();
            Classified classcheck = ProfileFrontend.GetClassified (queryClassifiedID);
            if (((queryclassifiedFlags & 32) != 32) && moneyModule != null) {
                //Single week
                if (!moneyModule.Charge (remoteClient.AgentId, queryclassifiedPrice, "Add Classified", TransactionType.ClassifiedCharge)) {
                    remoteClient.SendAlertMessage ("You do not have enough money to create this classified.");
                    return;
                }
            } else if (scheduledMoneyModule != null) {
                //Auto-renew
                if (classcheck != null)
                    scheduledMoneyModule.RemoveFromScheduledCharge ("[Classified: " + queryClassifiedID + "]");

                var payOK = scheduledMoneyModule.Charge (
                                remoteClient.AgentId,                                           // who to charge
                                queryclassifiedPrice,                                           // how much
                                "Add Reoccurring Classified (" + queryClassifiedID + ")",       // description
                                TransactionType.ClassifiedCharge,                               // transaction type
                                "[Classified: " + queryClassifiedID + "]",                      // scheduler identifier
                                true,                                                           // charger immediately
                                false);                                                         // run once
                if (!payOK) {
                    remoteClient.SendAlertMessage ("You do not have enough money to create this classified.");
                    return;
                }
            }

            UUID creatorUUID = remoteClient.AgentId;
            UUID classifiedUUID = queryClassifiedID;
            uint category = queryCategory;
            string name = queryName;
            string description = queryDescription;
            uint parentestate = queryParentEstate;
            UUID snapshotUUID = querySnapshotID;
            string simname = remoteClient.Scene.RegionInfo.RegionName;
            Vector3 globalpos = queryGlobalPos;
            byte classifiedFlags = queryclassifiedFlags;
            int classifiedPrice = queryclassifiedPrice;

            UUID parceluuid = p.CurrentParcelUUID;
            string parcelname = "Unknown";
            IParcelManagementModule parcelManagement = remoteClient.Scene.RequestModuleInterface<IParcelManagementModule> ();
            if (parcelManagement != null) {
                ILandObject parcel = parcelManagement.GetLandObject (p.AbsolutePosition.X, p.AbsolutePosition.Y);
                if (parcel != null) {
                    parcelname = parcel.LandData.Name;
                    parceluuid = parcel.LandData.GlobalID;
                }
            }

            uint creationdate = (uint)Util.UnixTimeSinceEpoch ();

            uint expirationdate = (uint)Util.UnixTimeSinceEpoch () + (365 * 24 * 60 * 60);

            Classified classified = new Classified {
                ClassifiedUUID = classifiedUUID,
                CreatorUUID = creatorUUID,
                CreationDate = creationdate,
                ExpirationDate = expirationdate,
                Category = category,
                Name = name,
                Description = description,
                ParcelUUID = parceluuid,
                ParentEstate = parentestate,
                SnapshotUUID = snapshotUUID,
                SimName = simname,
                GlobalPos = globalpos,
                ParcelName = parcelname,
                ClassifiedFlags = classifiedFlags,
                PriceForListing = classifiedPrice,
                ScopeID = remoteClient.ScopeID
            };

            ProfileFrontend.AddClassified (classified);
        }
        public List<Classified> GetClassifiedsInRegion(string regionName)
        {
            object remoteValue = DoRemote(regionName);
            if (remoteValue != null || m_doRemoteOnly)
                return (List<Classified>) remoteValue;

            QueryFilter filter = new QueryFilter();
            filter.andFilters["SimName"] = regionName;
            List<string> retVal = GD.Query(new[] { "*" }, m_userClassifiedsTable, filter, null, null, null);

            if (retVal.Count == 0)
                return new List<Classified>();

            List<Classified> Classifieds = new List<Classified>();
            for (int i = 0; i < retVal.Count; i += 9)
            {
                Classified classified = new Classified();
                //Pull the classified out of OSD
                classified.FromOSD((OSDMap) OSDParser.DeserializeJson(retVal[i + 6]));
                Classifieds.Add(classified);
            }
            return Classifieds;
        }
        public Classified GetClassifiedByID(UUID id)
        {
            object remoteValue = DoRemote(id);
            if (remoteValue != null || m_doRemoteOnly)
                return (Classified) remoteValue;

            QueryFilter filter = new QueryFilter();
            Dictionary<string, object> where = new Dictionary<string, object>(1);
            where.Add("ClassifiedUUID", id);
            filter.andFilters = where;

            List<string> retVal = GD.Query(new[] { "*" }, m_userClassifiedsTable, filter, null, null, null);

            if ((retVal == null) || (retVal.Count == 0)) return null;

            Classified classified = new Classified();
            classified.FromOSD((OSDMap) OSDParser.DeserializeJson(retVal[6]));
            return classified;
        }
        public List<DirClassifiedReplyData> FindClassifieds(string queryText, string category, uint queryFlags,
                                                            int StartQuery, UUID scopeID)
        {
            object remoteValue = DoRemote(queryText, category, queryFlags, StartQuery, scopeID);
            if (remoteValue != null || m_doRemoteOnly)
                return (List<DirClassifiedReplyData>) remoteValue;

            QueryFilter filter = new QueryFilter();

            filter.andLikeFilters["Name"] = "%" + queryText + "%";
            if (int.Parse(category) != (int) DirectoryManager.ClassifiedCategories.Any) //Check the category
                filter.andFilters["Category"] = category;
            if (scopeID != UUID.Zero)
                filter.andFilters["ScopeID"] = scopeID;

            List<string> retVal = GD.Query(new[] {"*"}, m_userClassifiedsTable, filter, null, (uint) StartQuery, 50);
            if (retVal.Count == 0)
                return new List<DirClassifiedReplyData>();

            List<DirClassifiedReplyData> Data = new List<DirClassifiedReplyData>();
            for (int i = 0; i < retVal.Count; i += 9)
            {
                //Pull the classified out of OSD
                Classified classified = new Classified();
                classified.FromOSD((OSDMap) OSDParser.DeserializeJson(retVal[i + 5]));

                DirClassifiedReplyData replyData = new DirClassifiedReplyData
                                                       {
                                                           classifiedFlags = classified.ClassifiedFlags,
                                                           classifiedID = classified.ClassifiedUUID,
                                                           creationDate = classified.CreationDate,
                                                           expirationDate = classified.ExpirationDate,
                                                           price = classified.PriceForListing,
                                                           name = classified.Name
                                                       };
                //Check maturity levels
                if ((replyData.classifiedFlags & (uint) DirectoryManager.ClassifiedFlags.Mature) !=
                    (uint) DirectoryManager.ClassifiedFlags.Mature)
                {
                    if ((queryFlags & (uint) DirectoryManager.ClassifiedQueryFlags.Mature) ==
                        (uint) DirectoryManager.ClassifiedQueryFlags.Mature)
                        Data.Add(replyData);
                }
                else
                    //Its Mature, add all
                    Data.Add(replyData);
            }
            return Data;
        }
        public Classified GetClassified(UUID queryClassifiedID)
        {
            if (m_doRemoteOnly) {
                object remoteValue = DoRemote (queryClassifiedID);
                return remoteValue != null ? (Classified)remoteValue : null;
            }

            QueryFilter filter = new QueryFilter();
            filter.andFilters["ClassifiedUUID"] = queryClassifiedID;

            List<string> query = GD.Query(new[] { "*" }, m_userClassifiedsTable, filter, null, null, null);

            if (query.Count < 9)
                return null;
            
            Classified classified = new Classified();
            classified.FromOSD((OSDMap) OSDParser.DeserializeJson(query[6]));
            return classified;
        }
        public List<Classified> GetClassifieds(UUID ownerID)
        {
            if (m_doRemoteOnly) {
                object remoteValue = DoRemote (ownerID);
                return remoteValue != null ? (List<Classified>)remoteValue : new List<Classified> ();
            }

            QueryFilter filter = new QueryFilter();
            filter.andFilters["OwnerUUID"] = ownerID;

            List<string> query = GD.Query(new[] { "*" }, m_userClassifiedsTable, filter, null, null, null);

            List<Classified> classifieds = new List<Classified>();
            for (int i = 0; i < query.Count; i += 9)
            {
                Classified classified = new Classified();
                classified.FromOSD((OSDMap) OSDParser.DeserializeJson(query[i + 6]));
                classifieds.Add(classified);
            }
            return classifieds;
        }
        public List<Classified> GetAllClassifieds (int category, uint classifiedFlags)
        {
            List<Classified> classifieds = new List<Classified> ();

            if (m_doRemoteOnly) {
                object remoteValue = DoRemote (category, classifiedFlags);
                return remoteValue != null ? (List<Classified>)remoteValue : classifieds;
            }

            QueryFilter filter = new QueryFilter ();

            if (category != (int)DirectoryManager.ClassifiedCategories.Any) //Check the category
                filter.andFilters ["Category"] = category.ToString();

            List<string> retVal = GD.Query (new [] { "*" }, m_userClassifiedsTable, filter, null, null, null);

            if (retVal.Count != 0) {
                for (int i = 0; i < retVal.Count; i += 9) {
                    Classified classified = new Classified ();

                    //Pull the classified out of OSD
                    classified.FromOSD ((OSDMap)OSDParser.DeserializeJson (retVal [i + 6]));

                    //Check maturity levels
                    if (classifiedFlags != (uint)DirectoryManager.ClassifiedQueryFlags.All) {
                        if (classifiedFlags  == classified.ClassifiedFlags) // required rating All, PG, Mature, Adult
                            classifieds.Add (classified);
                    } else
                        // add all
                        classifieds.Add (classified);
                }
            }

            return classifieds;
        }