diff --git a/indra/llmessage/llclassifiedflags.h b/indra/llmessage/llclassifiedflags.h
index 9c6c268b397e76d5e9d51a8494e22b5d827e2cf2..dafd0ceb62560feba8d65bd2fa9df18c5f5d2d55 100644
--- a/indra/llmessage/llclassifiedflags.h
+++ b/indra/llmessage/llclassifiedflags.h
@@ -47,6 +47,7 @@ const U8 CLASSIFIED_QUERY_INC_ADULT         = 1 << 6;
 const U8 CLASSIFIED_QUERY_INC_NEW_VIEWER    = (CLASSIFIED_QUERY_INC_PG | CLASSIFIED_QUERY_INC_MATURE | CLASSIFIED_QUERY_INC_ADULT);
 
 const S32 MAX_CLASSIFIEDS = 100;
+const S32 MINIMUM_PRICE_FOR_LISTING = 50;  // L$
 
 // This function is used in AO viewers to pack old query flags into the request
 // so that they can talk to old dataservers properly. When the AO servers are deployed on agni
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ce8b7dcf041dd7909f87a1195d8e4973a944db07..48a6c314a66c4cf28188f5378cc0790f14298aa1 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -113,7 +113,6 @@ set(viewer_SOURCE_FILES
     bdfloaterposer.cpp
     bdfloaterposecreator.cpp
     bdposingmotion.cpp
-    fsfloatersearch.cpp
     fslslpreproc.cpp
     fslslpreprocviewer.cpp
     gltfscenemanager.cpp
@@ -130,6 +129,7 @@ set(viewer_SOURCE_FILES
     llagentbenefits.cpp
     llagentcamera.cpp
     llagentdata.cpp
+    llagenthandler.cpp
     llagentlanguage.cpp
     llagentlistener.cpp
     llagentpicksinfo.cpp
@@ -167,6 +167,7 @@ set(viewer_SOURCE_FILES
     llchiclet.cpp
     llchicletbar.cpp
     llclassifiedinfo.cpp
+    llclassifieditem.cpp
     llcofwearables.cpp
     llcolorswatch.cpp
     llcommanddispatcherlistener.cpp
@@ -263,6 +264,7 @@ set(viewer_SOURCE_FILES
     llfloatercreatelandmark.cpp
     llfloaterdeleteprefpreset.cpp
     llfloaterdestinations.cpp
+    llfloaterdirectory.cpp
     llfloaterdisplayname.cpp
     llfloatereditenvironmentbase.cpp
     llfloatereditextdaycycle.cpp
@@ -329,12 +331,14 @@ set(viewer_SOURCE_FILES
     llfloaterperformance.cpp
     llfloaterperms.cpp
     llfloaterprofile.cpp
+    llfloaterprofilelegacy.cpp
     llfloaterpreference.cpp
     llfloaterpreferencesgraphicsadvanced.cpp
     llfloaterpreferenceviewadvanced.cpp
     llfloaterpreviewtrash.cpp
     llfloaterprofiletexture.cpp
     llfloaterprogressview.cpp
+    llfloaterpublishclassified.cpp
     llfloaterregiondebugconsole.cpp
     llfloaterregioninfo.cpp
     llfloaterreporter.cpp
@@ -367,6 +371,7 @@ set(viewer_SOURCE_FILES
     llfloatervoiceeffect.cpp
     llfloatervoicevolume.cpp
     llfloaterwebcontent.cpp
+    llfloaterwebprofile.cpp
     llfloaterwhitelistentry.cpp
     llfloaterwindowsize.cpp
     llfloaterworldmap.cpp
@@ -485,6 +490,7 @@ set(viewer_SOURCE_FILES
     lloutputmonitorctrl.cpp
     llpanelappearancetab.cpp
     llpanelavatar.cpp
+    llpanelavatarlegacy.cpp
     llpanelavatartag.cpp
     llpanelblockedlist.cpp
     llpanelclassified.cpp
@@ -494,6 +500,7 @@ set(viewer_SOURCE_FILES
     llpaneleditwearable.cpp
     llpanelemojicomplete.cpp
     llpanelenvironment.cpp
+    llpaneleventinfo.cpp
     llpanelexperiencelisteditor.cpp
     llpanelexperiencelog.cpp
     llpanelexperiencepicker.cpp
@@ -533,6 +540,7 @@ set(viewer_SOURCE_FILES
     llpanelpeople.cpp
     llpanelpeoplemenus.cpp
     llpanelpermissions.cpp
+    llpanelpick.cpp
     llpanelplaceinfo.cpp
     llpanelplaceprofile.cpp
     llpanelplaces.cpp
@@ -541,8 +549,17 @@ set(viewer_SOURCE_FILES
     llpanelpresetspulldown.cpp
     llpanelprimmediacontrols.cpp
     llpanelprofile.cpp
+    llpanelprofilelegacy.cpp
     llpanelprofileclassifieds.cpp
     llpanelprofilepicks.cpp
+    llpanelsearchbase.cpp
+    llpanelsearchclassifieds.cpp
+    llpanelsearchevents.cpp
+    llpanelsearchgroups.cpp
+    llpanelsearchlandsales.cpp
+    llpanelsearchpeople.cpp
+    llpanelsearchplaces.cpp
+    llpanelsearchweb.cpp
     llpanelsnapshot.cpp
     llpanelsnapshotinventory.cpp
     llpanelsnapshotlocal.cpp
@@ -575,6 +592,7 @@ set(viewer_SOURCE_FILES
     llpersistentnotificationstorage.cpp
     llphysicsmotion.cpp
     llphysicsshapebuilderutil.cpp
+    llpickitem.cpp
     llpipelinelistener.cpp
     llplacesinventorybridge.cpp
     llplacesinventorypanel.cpp
@@ -591,6 +609,7 @@ set(viewer_SOURCE_FILES
     llpreviewtexture.cpp
     llproductinforequest.cpp
     llprogressview.cpp
+    llprofileimagepicker.cpp
     llrecentpeople.cpp
     llreflectionmap.cpp
     llreflectionmapmanager.cpp
@@ -842,7 +861,6 @@ set(viewer_HEADER_FILES
     bdfloaterposer.h
     bdfloaterposecreator.h
     bdposingmotion.h
-    fsfloatersearch.h
     fslslpreproc.h
     fslslpreprocviewer.h
     gltfscenemanager.h
@@ -898,6 +916,7 @@ set(viewer_HEADER_FILES
     llchiclet.h
     llchicletbar.h
     llclassifiedinfo.h
+    llclassifieditem.h
     llcofwearables.h
     llcolorswatch.h
     llcommanddispatcherlistener.h
@@ -994,6 +1013,7 @@ set(viewer_HEADER_FILES
     llfloatercreatelandmark.h
     llfloaterdeleteprefpreset.h
     llfloaterdestinations.h
+    llfloaterdirectory.h
     llfloaterdisplayname.h
     llfloatereditenvironmentbase.h
     llfloatereditextdaycycle.h
@@ -1063,12 +1083,14 @@ set(viewer_HEADER_FILES
     llfloaterperformance.h
     llfloaterperms.h
     llfloaterprofile.h
+    llfloaterprofilelegacy.h
     llfloaterpreference.h
     llfloaterpreferencesgraphicsadvanced.h
     llfloaterpreferenceviewadvanced.h
     llfloaterpreviewtrash.h
     llfloaterprofiletexture.h
     llfloaterprogressview.h
+    llfloaterpublishclassified.h
     llfloaterregiondebugconsole.h
     llfloaterregioninfo.h
     llfloaterreporter.h
@@ -1101,6 +1123,7 @@ set(viewer_HEADER_FILES
     llfloatervoiceeffect.h
     llfloatervoicevolume.h
     llfloaterwebcontent.h
+    llfloaterwebprofile.h
     llfloaterwhitelistentry.h
     llfloaterwindowsize.h
     llfloaterworldmap.h
@@ -1208,6 +1231,7 @@ set(viewer_HEADER_FILES
     lloutputmonitorctrl.h
     llpanelappearancetab.h
     llpanelavatar.h
+    llpanelavatarlegacy.h
     llpanelavatartag.h
     llpanelblockedlist.h
     llpanelclassified.h
@@ -1217,6 +1241,7 @@ set(viewer_HEADER_FILES
     llpaneleditwearable.h
     llpanelemojicomplete.h
     llpanelenvironment.h
+    llpaneleventinfo.h
     llpanelexperiencelisteditor.h
     llpanelexperiencelog.h
     llpanelexperiencepicker.h
@@ -1257,6 +1282,7 @@ set(viewer_HEADER_FILES
     llpanelpeople.h
     llpanelpeoplemenus.h
     llpanelpermissions.h
+    llpanelpick.h
     llpanelplaceinfo.h
     llpanelplaceprofile.h
     llpanelplaces.h
@@ -1265,8 +1291,17 @@ set(viewer_HEADER_FILES
     llpanelpresetspulldown.h
     llpanelprimmediacontrols.h
     llpanelprofile.h
+    llpanelprofilelegacy.h
     llpanelprofileclassifieds.h
     llpanelprofilepicks.h
+    llpanelsearchbase.h
+    llpanelsearchclassifieds.h
+    llpanelsearchevents.h
+    llpanelsearchgroups.h
+    llpanelsearchlandsales.h
+    llpanelsearchpeople.h
+    llpanelsearchplaces.h
+    llpanelsearchweb.h
     llpanelsnapshot.h
     llpanelteleporthistory.h
     llpaneltiptoast.h
@@ -1294,6 +1329,7 @@ set(viewer_HEADER_FILES
     llpersistentnotificationstorage.h
     llphysicsmotion.h
     llphysicsshapebuilderutil.h
+    llpickitem.h
     llpipelinelistener.h
     llplacesinventorybridge.h
     llplacesinventorypanel.h
@@ -1309,6 +1345,7 @@ set(viewer_HEADER_FILES
     llpreviewsound.h
     llpreviewtexture.h
     llproductinforequest.h
+    llprofileimagepicker.h
     llprogressview.h
     llrecentpeople.h
     llreflectionmap.h
diff --git a/indra/newview/alavataractions.cpp b/indra/newview/alavataractions.cpp
index b9bdbc2b13799bb4b0ed5020cfef95a9253d0a4c..7668577325aeea6de6fa34ebca902993d5e70b9c 100644
--- a/indra/newview/alavataractions.cpp
+++ b/indra/newview/alavataractions.cpp
@@ -36,8 +36,11 @@
 #include "roles_constants.h"
 
 #include "llagent.h"
+#include "llavataractions.h"
+#include "llfloaterreg.h"
 #include "llfloaterregioninfo.h"
 #include "llfloaterreporter.h"
+#include "llfloaterwebcontent.h"
 #include "llslurl.h"
 #include "llviewercontrol.h"
 #include "llviewermenu.h"
@@ -853,3 +856,21 @@ bool ALAvatarActions::handleGodKick(const LLSD& notification, const LLSD& respon
     }
     return false;
 }
+
+// Webprofile junk... for posterity!
+
+static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+    LLFloaterWebContent::Params p;
+    p.url(getProfileURL(av_name.getAccountName())).id(agent_id.asString());
+    LLFloaterReg::showInstance("webprofile", p);
+}
+
+// static
+void ALAvatarActions::showWebProfile(const LLUUID& id)
+{
+    if (id.notNull())
+    {
+        LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
+    }
+}
diff --git a/indra/newview/alavataractions.h b/indra/newview/alavataractions.h
index d6bb2f1792f574399b15a5751e95e94876b9da42..03dfe49e516ae470696a6b66fa54376e743c5a44 100644
--- a/indra/newview/alavataractions.h
+++ b/indra/newview/alavataractions.h
@@ -94,6 +94,9 @@ class ALAvatarActions
     static void godFreeze(const LLUUID& id);
     static void godUnfreeze(const LLUUID& id);
 
+    // Webprofile
+    static void showWebProfile(const LLUUID& id);
+
 private:
     static bool handleParcelFreeze(const LLSD& notification, const LLSD& response);
     static bool handleParcelEject(const LLSD& notification, const LLSD& response);
diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp
deleted file mode 100644
index 286bcdf2fe82261df17563aaeb6178dfe7ec444d..0000000000000000000000000000000000000000
--- a/indra/newview/fsfloatersearch.cpp
+++ /dev/null
@@ -1,3155 +0,0 @@
-/**
- * @file fsfloatersearch.cpp
- * @brief Firestorm Search Floater
- *
- * $LicenseInfo:firstyear=2012&license=fsviewerlgpl$
- * Phoenix Firestorm Viewer Source Code
- * Copyright (C) 2012, Cinder Roxley <cinder.roxley@phoenixviewer.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
- * http://www.firestormviewer.org
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "fsfloatersearch.h"
-
-#include "lldispatcher.h"
-#include "llagent.h"
-#include "llavataractions.h"
-#include "llavatarname.h"
-#include "llavatarnamecache.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llclassifiedflags.h"
-#include "llclassifiedinfo.h"
-#include "llcombobox.h"
-#include "lldateutil.h"
-#include "lleventflags.h"
-#include "lleventnotifier.h"
-#include "llfloaterreg.h"
-#include "llfloaterworldmap.h"
-#include "llgroupactions.h"
-#include "llgroupmgr.h"
-#include "llloadingindicator.h"
-#include "lllogininstance.h"
-#include "llnotificationsutil.h"
-#include "llpanelprofile.h"
-#include "llpanelprofileclassifieds.h"
-#include "llparcel.h"
-#include "llproductinforequest.h"
-#include "llqueryflags.h"
-#include "llregionhandle.h"
-#include "llremoteparcelrequest.h"
-#include "lltimer.h"
-#include "lltrans.h"
-#include "llviewercontrol.h"
-#include "llviewergenericmessage.h"
-#include "llviewernetwork.h"
-#include "llviewerregion.h"
-#include "llworldmapmessage.h"
-#include "message.h"
-#include <boost/tokenizer.hpp>
-#include <boost/algorithm/string.hpp>
-#include <string>
-
-static const S32 MIN_SEARCH_STRING_SIZE = 2;
-static const S32 RESULT_PAGE_SIZE = 100;
-
-std::string filterShortWords(std::string query_string);
-void fillSearchComboBox(LLSearchComboBox* search_combo);
-
-////////////////////////////////////////
-//          Observer Classes          //
-////////////////////////////////////////
-
-class FSSearchRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver
-{
-public:
-    FSSearchRemoteParcelInfoObserver(FSFloaterSearch* floater, bool for_events) : LLRemoteParcelInfoObserver(),
-        mParent(floater),
-        mForEvents(for_events)
-    {}
-
-    ~FSSearchRemoteParcelInfoObserver()
-    {
-        // remove any in-flight observers
-        std::set<LLUUID>::iterator it;
-        for (it = mParcelIDs.begin(); it != mParcelIDs.end(); ++it)
-        {
-            const LLUUID &id = *it;
-            LLRemoteParcelInfoProcessor::getInstance()->removeObserver(id, this);
-        }
-        mParcelIDs.clear();
-    }
-
-    /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data)
-    {
-        if (mParent)
-        {
-            if (mForEvents)
-            {
-                mParent->displayEventParcelImage(parcel_data);
-            }
-            else
-            {
-                mParent->displayParcelDetails(parcel_data);
-            }
-        }
-        mParcelIDs.erase(parcel_data.parcel_id);
-        LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_data.parcel_id, this);
-    }
-
-    /*virtual*/ void setParcelID(const LLUUID& parcel_id)
-    {
-        if (!parcel_id.isNull())
-        {
-            mParcelIDs.insert(parcel_id);
-            LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this);
-            LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id);
-        }
-    }
-
-    /*virtual*/ void setErrorStatus(S32 status, const std::string& reason)
-    {
-        LL_WARNS("Search") << "Can't complete remote parcel request. Http Status: " << status << ". Reason : " << reason << LL_ENDL;
-    }
-private:
-    std::set<LLUUID>    mParcelIDs;
-    FSFloaterSearch*    mParent;
-    bool                mForEvents;
-};
-
-///// Avatar Properties Observer /////
-
-class FSSearchAvatarPropertiesObserver : public LLAvatarPropertiesObserver
-{
-public:
-    FSSearchAvatarPropertiesObserver(FSFloaterSearch* floater) : LLAvatarPropertiesObserver(),
-    mParent(floater)
-    {}
-
-    ~FSSearchAvatarPropertiesObserver()
-    {
-        // remove any in-flight observers
-        std::set<LLUUID>::iterator it;
-        for (it = mAvatarIDs.begin(); it != mAvatarIDs.end(); ++it)
-        {
-            const LLUUID &id = *it;
-            LLAvatarPropertiesProcessor::getInstance()->removeObserver(id, this);
-        }
-        mAvatarIDs.clear();
-    }
-
-    void processProperties(void* data, EAvatarProcessorType type)
-    {
-        if (!data)
-            return;
-
-        if (APT_PROPERTIES == type)
-        {
-            LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
-            if (avatar_data)
-            {
-                mParent->displayAvatarDetails(avatar_data);
-                LLAvatarPropertiesProcessor::getInstance()->removeObserver(avatar_data->avatar_id, this);
-            }
-        }
-        else if (APT_PROPERTIES_LEGACY == type)
-        {
-            LLAvatarData avatar_data(*static_cast<LLAvatarLegacyData*>(data));
-            mParent->displayAvatarDetails(&avatar_data);
-            LLAvatarPropertiesProcessor::getInstance()->removeObserver(avatar_data.avatar_id, this);
-        }
-        if (APT_CLASSIFIED_INFO == type)
-        {
-            LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
-            if (c_info)
-            {
-                mParent->displayClassifiedDetails(c_info);
-                LLAvatarPropertiesProcessor::getInstance()->removeObserver(c_info->classified_id, this);
-                std::string url = gAgent.getRegionCapability("SearchStatRequest");
-                if (!url.empty())
-                {
-                    LL_INFOS("Search") << "Classified stat request via capability" << LL_ENDL;
-                    LLSD body;
-                    body["classified_id"] = c_info->classified_id;
-                    LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body, boost::bind(&LLPanelProfileClassified::handleSearchStatResponse, c_info->classified_id, _1));
-                }
-            }
-        }
-    }
-private:
-    std::set<LLUUID>    mAvatarIDs;
-    FSFloaterSearch*    mParent;
-};
-
-///// Group Info Observer /////
-
-class FSSearchGroupInfoObserver : public LLGroupMgrObserver
-{
-public:
-    FSSearchGroupInfoObserver(const LLUUID& group_id, FSFloaterSearch* parent) :
-    LLGroupMgrObserver(group_id),
-    mParent(parent)
-    {
-        LLGroupMgr* groupmgr = LLGroupMgr::getInstance();
-        if (!group_id.isNull() && groupmgr)
-        {
-            groupmgr->addObserver(this);
-            mID = group_id;
-            groupmgr->sendGroupPropertiesRequest(group_id);
-        }
-    }
-
-    ~FSSearchGroupInfoObserver()
-    {
-        LLGroupMgr::getInstance()->removeObserver(this);
-    }
-
-    void changed(LLGroupChange gc)
-    {
-        if (gc == GC_PROPERTIES)
-        {
-            LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID);
-            mParent->displayGroupDetails(group_data);
-            LLGroupMgr::getInstance()->removeObserver(this);
-        }
-    }
-private:
-    FSFloaterSearch*    mParent;
-    LLUUID              mID;
-};
-
-///// Silly Classified Clickthrough Class /////
-class FSDispatchClassifiedClickThrough : public LLDispatchHandler
-{
-public:
-    virtual bool operator()(
-        const LLDispatcher* dispatcher,
-        const std::string& key,
-        const LLUUID& invoice,
-        const sparam_t& strings)
-    {
-        if (strings.size() != 4) return false;
-        LLUUID classified_id(strings[0]);
-        S32 teleport_clicks = atoi(strings[1].c_str());
-        S32 map_clicks = atoi(strings[2].c_str());
-        S32 profile_clicks = atoi(strings[3].c_str());
-
-        LLPanelProfileClassified::setClickThrough(
-            classified_id, teleport_clicks, map_clicks, profile_clicks, false);
-
-        return true;
-    }
-};
-static FSDispatchClassifiedClickThrough sClassifiedClickThrough;
-
-SearchQuery::SearchQuery()
-: category("category", "")
-, query("query")
-{}
-
-////////////////////////////////////////
-//         The floater itself         //
-////////////////////////////////////////
-
-FSFloaterSearch::FSFloaterSearch(const Params& key)
-:   LLFloater(key)
-{
-    mRemoteParcelObserver = new FSSearchRemoteParcelInfoObserver(this, false);
-    mRemoteParcelEventLocationObserver = new FSSearchRemoteParcelInfoObserver(this, true);
-    mAvatarPropertiesObserver = new FSSearchAvatarPropertiesObserver(this);
-    mEventNotifierConnection = gEventNotifier.setNewEventCallback(boost::bind(&FSFloaterSearch::displayEventDetails, this, boost::placeholders::_1));
-}
-
-FSFloaterSearch::~FSFloaterSearch()
-{
-    mEventNotifierConnection.disconnect();
-    delete mRemoteParcelObserver;
-    delete mRemoteParcelEventLocationObserver;
-    delete mAvatarPropertiesObserver;
-    gGenericDispatcher.addHandler("classifiedclickthrough", nullptr);
-}
-
-// virtual
-void FSFloaterSearch::onOpen(const LLSD& key)
-{
-    Params p(key);
-    mPanelWeb->loadURL(p.search);
-    if (key.has("query"))
-    {
-        mTabContainer->selectTabPanel(mPanelWeb);
-    }
-    else if (key.has("tab") && key["tab"].asString() == "groups")
-    {
-        mTabContainer->selectTabPanel(mPanelGroups);
-    }
-
-    FSSearchPanelBase* current_panel = dynamic_cast<FSSearchPanelBase*>(mTabContainer->getCurrentPanel());
-    if (current_panel)
-    {
-        current_panel->focusDefaultElement();
-    }
-}
-
-//virtual
-void FSFloaterSearch::onClose(bool app_quitting)
-{
-    if (mTabContainer)
-    {
-        gSavedSettings.setS32("FSLastSearchTab", mTabContainer->getCurrentPanelIndex());
-    }
-}
-
-BOOL FSFloaterSearch::postBuild()
-{
-    childSetAction("people_profile_btn", boost::bind(&FSFloaterSearch::onBtnPeopleProfile, this));
-    childSetAction("people_message_btn", boost::bind(&FSFloaterSearch::onBtnPeopleIM, this));
-    childSetAction("people_friend_btn", boost::bind(&FSFloaterSearch::onBtnPeopleFriend, this));
-    childSetAction("group_profile_btn", boost::bind(&FSFloaterSearch::onBtnGroupProfile, this));
-    childSetAction("group_message_btn", boost::bind(&FSFloaterSearch::onBtnGroupChat, this));
-    childSetAction("group_join_btn", boost::bind(&FSFloaterSearch::onBtnGroupJoin, this));
-    childSetAction("event_reminder_btn", boost::bind(&FSFloaterSearch::onBtnEventReminder, this));
-    childSetAction("teleport_btn", boost::bind(&FSFloaterSearch::onBtnTeleport, this));
-    childSetAction("map_btn", boost::bind(&FSFloaterSearch::onBtnMap, this));
-    resetVerbs();
-
-    mPanelPeople        = findChild<FSPanelSearchPeople>("panel_ls_people");
-    mPanelGroups        = findChild<FSPanelSearchGroups>("panel_ls_groups");
-    mPanelPlaces        = findChild<FSPanelSearchPlaces>("panel_ls_places");
-    mPanelEvents        = findChild<FSPanelSearchEvents>("panel_ls_events");
-    mPanelLand          = findChild<FSPanelSearchLand>("panel_ls_land");
-    mPanelClassifieds   = findChild<FSPanelSearchClassifieds>("panel_ls_classifieds");
-    mPanelWeb           = findChild<FSPanelSearchWeb>("panel_ls_web");
-
-    mDetailsPanel =     getChild<LLPanel>("panel_ls_details");
-    mDetailTitle =      getChild<LLTextEditor>("title");
-    mDetailDesc =       getChild<LLTextEditor>("desc");
-    mDetailAux1 =       getChild<LLTextEditor>("aux1");
-    mDetailAux2 =       getChild<LLTextEditor>("aux2");
-    mDetailLocation =   getChild<LLTextEditor>("location");
-    mDetailSnapshot =   getChild<LLTextureCtrl>("snapshot");
-    mDetailSnapshotParcel = getChild<LLTextureCtrl>("snapshot_parcel");
-    mDetailMaturity =   getChild<LLIconCtrl>("maturity_icon");
-    mTabContainer =     getChild<LLTabContainer>("ls_tabs");
-
-    mTabContainer->setCommitCallback(boost::bind(&FSFloaterSearch::onTabChange, this));
-
-    flushDetails();
-
-    mDetailsPanel->setVisible(false);
-
-    mHasSelection = false;
-
-    if (!mTabContainer->selectTab(gSavedSettings.getS32("FSLastSearchTab")))
-    {
-        mTabContainer->selectFirstTab();
-    }
-
-    return TRUE;
-}
-
-void FSFloaterSearch::onTabChange()
-{
-    LLPanel* active_panel = mTabContainer->getCurrentPanel();
-
-    if (active_panel == mPanelWeb)
-    {
-        mDetailsPanel->setVisible(false);
-        mPanelWeb->resetFocusOnLoad();
-    }
-    else if (active_panel == mPanelPeople)
-    {
-        mDetailsPanel->setVisible(mHasSelection);
-    }
-
-    if (active_panel == mPanelPeople || active_panel == mPanelGroups)
-    {
-        mDetailSnapshotParcel->setVisible(FALSE);
-        mDetailSnapshot->setVisible(TRUE);
-    }
-    else if (active_panel == mPanelPlaces || active_panel == mPanelLand ||
-        active_panel == mPanelEvents || active_panel == mPanelClassifieds)
-    {
-        mDetailSnapshot->setVisible(FALSE);
-        mDetailSnapshotParcel->setVisible(TRUE);
-    }
-}
-
-//static
-template <class T>
-T* FSFloaterSearch::getSearchPanel(const std::string& panel_name)
-{
-    FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search");
-    if (search_instance && search_instance->mTabContainer)
-    {
-        return dynamic_cast<T*>(search_instance->mTabContainer->getPanelByName(panel_name));
-    }
-    else
-    {
-        return nullptr;
-    }
-}
-
-void FSFloaterSearch::onSelectedItem(const LLUUID& selected_item, ESearchCategory type)
-{
-    if (!selected_item.isNull())
-    {
-        mSelectedID = selected_item;
-        resetVerbs();
-        flushDetails();
-        switch (type)
-        {
-            case SC_AVATAR:
-            {
-                LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver);
-                LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(selected_item);
-            }
-                break;
-            case SC_GROUP:
-                mGroupPropertiesRequest = new FSSearchGroupInfoObserver(selected_item, this);
-                break;
-            case SC_PLACE:
-                mRemoteParcelObserver->setParcelID(selected_item);
-                break;
-            case SC_CLASSIFIED:
-                LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver);
-                LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(selected_item);
-                gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough);
-                break;
-        }
-        setLoadingProgress(true);
-    }
-}
-
-void FSFloaterSearch::onSelectedEvent(const S32 selected_event)
-{
-    resetVerbs();
-    flushDetails();
-
-    gMessageSystem->newMessageFast(_PREHASH_EventInfoRequest);
-    gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-    gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID);
-    gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
-    gMessageSystem->nextBlockFast(_PREHASH_EventData);
-    gMessageSystem->addU32Fast(_PREHASH_EventID, selected_event);
-    gAgent.sendReliableMessage();
-}
-
-void FSFloaterSearch::displayParcelDetails(const LLParcelData& parcel_data)
-{
-    S32 region_x;
-    S32 region_y;
-    S32 region_z;
-    region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS;
-    region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS;
-    region_z = ll_round(parcel_data.global_z);
-    // HACK: Flag 0x2 == adult region,
-    // Flag 0x1 == mature region, otherwise assume PG
-    if (parcel_data.flags & 0x2)
-    {
-        mDetailMaturity->setValue("Parcel_R_Dark");
-    }
-    else if (parcel_data.flags & 0x1)
-    {
-        mDetailMaturity->setValue("Parcel_M_Dark");
-    }
-    else
-    {
-        mDetailMaturity->setValue("Parcel_PG_Dark");
-    }
-
-    LLStringUtil::format_map_t map;
-    map["DWELL"] = llformat("%.0f", (F64)parcel_data.dwell);
-    map["AREA"] = llformat("%d m²", parcel_data.actual_area);
-    map["LOCATION"] = llformat("%s (%d, %d, %d)", parcel_data.sim_name.c_str(), region_x, region_y, region_z);
-
-    mParcelGlobal = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z);
-    mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_places" || mTabContainer->getCurrentPanel()->getName() == "panel_ls_land");
-    mHasSelection = true;
-    mDetailMaturity->setVisible(true);
-    mDetailTitle->setValue(parcel_data.name);
-    mDetailDesc->setValue(parcel_data.desc);
-    mDetailAux1->setValue(getString("string.traffic", map));
-    mDetailAux2->setValue(getString("string.area", map));
-    mDetailLocation->setValue(getString("string.location", map));
-    mDetailSnapshotParcel->setValue(parcel_data.snapshot_id);
-    childSetVisible("teleport_btn", true);
-    childSetVisible("map_btn", true);
-    setLoadingProgress(false);
-}
-
-void FSFloaterSearch::displayAvatarDetails(LLAvatarData* avatar_data)
-{
-    if (avatar_data)
-    {
-        LLStringUtil::format_map_t map;
-        map["AGE"] = LLDateUtil::ageFromDate(avatar_data->born_on, LLDate::now());
-        if (avatar_data->partner_id.notNull())
-        {
-            map["PARTNER"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString();
-            mDetailAux2->setValue(getString("string.partner", map));
-        }
-
-        mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_people");
-        mHasSelection = true;
-        mDetailTitle->setValue(LLTrans::getString("LoadingData"));
-        mDetailDesc->setValue(avatar_data->about_text);
-        mDetailSnapshot->setValue(avatar_data->image_id);
-        mDetailAux1->setValue(avatar_data->hide_age ? "" : getString("string.age", map));
-        LLAvatarNameCache::get(avatar_data->avatar_id, boost::bind(&FSFloaterSearch::avatarNameUpdatedCallback,this, _1, _2));
-        childSetVisible("people_profile_btn", true);
-        childSetVisible("people_message_btn", true);
-        childSetVisible("people_friend_btn", true);
-        getChildView("people_friend_btn")->setEnabled(!LLAvatarActions::isFriend(avatar_data->avatar_id));
-    }
-}
-
-void FSFloaterSearch::displayGroupDetails(LLGroupMgrGroupData*& group_data)
-{
-    if (group_data)
-    {
-        LLStringUtil::format_map_t map;
-        map["MEMBER_COUNT"] = llformat("%d",group_data->mMemberCount);
-        map["FOUNDER"] = LLSLURL("agent", group_data->mFounderID, "inspect").getSLURLString();
-
-        mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_groups");
-        mHasSelection = true;
-        mDetailTitle->setValue(LLTrans::getString("LoadingData"));
-        mDetailDesc->setValue(group_data->mCharter);
-        mDetailSnapshot->setValue(group_data->mInsigniaID);
-        mDetailAux1->setValue(getString("string.members", map));
-        mDetailAux2->setValue(getString("string.founder", map));
-        LLGroupData agent_gdatap;
-        bool is_member = gAgent.getGroupData(getSelectedID(),agent_gdatap) || gAgent.isGodlike();
-        bool join_btn_enabled = !is_member && group_data->mOpenEnrollment;
-        childSetVisible("group_profile_btn", true);
-        childSetVisible("group_message_btn", true);
-        childSetVisible("group_join_btn", true);
-        getChildView("group_join_btn")->setEnabled(join_btn_enabled);
-        getChildView("group_message_btn")->setEnabled(is_member);
-        gCacheName->getGroup(getSelectedID(), boost::bind(&FSFloaterSearch::groupNameUpdatedCallback, this, _1, _2, _3));
-    }
-}
-
-void FSFloaterSearch::displayClassifiedDetails(LLAvatarClassifiedInfo*& c_info)
-{
-    if (c_info)
-    {
-        if (c_info->flags & CLASSIFIED_FLAG_MATURE)
-        {
-            mDetailMaturity->setValue("Parcel_M_Dark");
-        }
-        else
-        {
-            mDetailMaturity->setValue("Parcel_PG_Dark");
-        }
-
-        LLStringUtil::format_map_t map;
-        map["LISTING_PRICE"] = llformat("L$%d", c_info->price_for_listing);
-        map["SLURL"] = LLSLURL("parcel", c_info->parcel_id, "about").getSLURLString();
-
-        mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_classifieds");
-        mHasSelection = true;
-        mDetailMaturity->setVisible(true);
-        mParcelGlobal = c_info->pos_global;
-        mDetailTitle->setValue(c_info->name);
-        mDetailDesc->setValue(c_info->description);
-        mDetailSnapshotParcel->setValue(c_info->snapshot_id);
-        mDetailAux1->setValue(getString("string.listing_price", map));
-        mDetailLocation->setValue(getString("string.slurl", map));
-        childSetVisible("teleport_btn", true);
-        childSetVisible("map_btn", true);
-        setLoadingProgress(false);
-    }
-}
-
-bool FSFloaterSearch::displayEventDetails(LLEventStruct event)
-{
-    if (event.flags == EVENT_FLAG_ADULT)
-    {
-        mDetailMaturity->setValue("Parcel_R_Dark");
-    }
-    else if (event.flags == EVENT_FLAG_MATURE)
-    {
-        mDetailMaturity->setValue("Parcel_M_Dark");
-    }
-    else
-    {
-        mDetailMaturity->setValue("Parcel_PG_Dark");
-    }
-
-    S32 region_x;
-    S32 region_y;
-    S32 region_z;
-    region_x = (S64)ll_round(event.globalPos.mdV[VX]) % REGION_WIDTH_UNITS;
-    region_y = (S64)ll_round(event.globalPos.mdV[VY]) % REGION_WIDTH_UNITS;
-    region_z = (S32)ll_round(event.globalPos.mdV[VZ]);
-    LLStringUtil::format_map_t map;
-    map["DURATION"] = llformat("%d:%.2d", event.duration / 60, event.duration % 60);
-    map["LOCATION"] = llformat("%s (%d, %d, %d)", event.simName.c_str(), region_x, region_y, region_z);
-    if (event.cover > 0)
-    {
-        map["COVERCHARGE"] = llformat("L$%d", event.cover);
-        mDetailAux2->setValue(getString("string.covercharge", map));
-    }
-
-    mParcelGlobal = event.globalPos;
-    mEventID = event.eventId;
-    mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_events");
-    mHasSelection = true;
-    mDetailMaturity->setVisible(true);
-    mDetailTitle->setValue(event.eventName);
-    mDetailDesc->setValue(event.desc);
-    mDetailAux1->setValue(getString("string.duration", map));
-    mDetailLocation->setValue(getString("string.location", map));
-    mDetailSnapshotParcel->setValue(LLUUID::null);
-    childSetVisible("teleport_btn", true);
-    childSetVisible("map_btn", true);
-    childSetVisible("event_reminder_btn", true);
-
-    LLWorldMapMessage::getInstance()->sendNamedRegionRequest(event.simName, boost::bind(&FSFloaterSearch::regionHandleCallback, this, _1, event.globalPos), "", false);
-    return true;
-}
-
-void FSFloaterSearch::regionHandleCallback(U64 region_handle, LLVector3d pos_global)
-{
-    std::string url = gAgent.getRegionCapability("RemoteParcelRequest");
-    if (!url.empty())
-    {
-        auto region_origin = from_region_handle(region_handle);
-        LLVector3 pos_region(LLVector3(pos_global - region_origin));
-
-        LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url,
-            LLUUID::null, pos_region, pos_global, mRemoteParcelEventLocationObserver->getObserverHandle());
-    }
-    else
-    {
-        setLoadingProgress(false);
-    }
-}
-
-void FSFloaterSearch::displayEventParcelImage(const LLParcelData& parcel_data)
-{
-    mDetailSnapshotParcel->setValue(parcel_data.snapshot_id);
-    setLoadingProgress(false);
-}
-
-void FSFloaterSearch::avatarNameUpdatedCallback(const LLUUID& id, const LLAvatarName& av_name)
-{
-    if (id == getSelectedID())
-    {
-        mDetailTitle->setValue(av_name.getCompleteName());
-        setLoadingProgress(false);
-    }
-    // Otherwise possibly a request for an older selection, ignore it.
-}
-
-void FSFloaterSearch::groupNameUpdatedCallback(const LLUUID& id, const std::string& name, bool is_group)
-{
-    if (id == getSelectedID())
-    {
-        mDetailTitle->setValue( LLSD(name) );
-        setLoadingProgress(false);
-    }
-    // Otherwise possibly a request for an older selection, ignore it.
-}
-
-void FSFloaterSearch::setLoadingProgress(bool started)
-{
-    LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("loading");
-
-    indicator->setVisible(started);
-
-    if (started)
-    {
-        indicator->start();
-    }
-    else
-    {
-        indicator->stop();
-    }
-}
-
-void FSFloaterSearch::resetVerbs()
-{
-    childSetVisible("people_profile_btn", false);
-    childSetVisible("people_message_btn", false);
-    childSetVisible("people_friend_btn", false);
-    childSetVisible("group_profile_btn", false);
-    childSetVisible("group_message_btn", false);
-    childSetVisible("group_join_btn", false);
-    childSetVisible("event_reminder_btn", false);
-    childSetVisible("teleport_btn", false);
-    childSetVisible("map_btn", false);
-}
-
-void FSFloaterSearch::flushDetails()
-{
-    mDetailTitle->setValue("");
-    mDetailDesc->setValue("");
-    mDetailAux1->setValue("");
-    mDetailAux2->setValue("");
-    mDetailLocation->setValue("");
-    mDetailSnapshot->setValue(LLSD());
-    mDetailMaturity->setVisible(false);
-    mParcelGlobal.setZero();
-}
-
-void FSFloaterSearch::onBtnPeopleProfile()
-{
-    LLAvatarActions::showProfile(getSelectedID());
-}
-
-void FSFloaterSearch::onBtnPeopleIM()
-{
-    LLAvatarActions::startIM(getSelectedID());
-}
-
-void FSFloaterSearch::onBtnPeopleFriend()
-{
-    LLAvatarActions::requestFriendshipDialog(getSelectedID());
-}
-
-void FSFloaterSearch::onBtnGroupProfile()
-{
-    LLGroupActions::show(getSelectedID());
-}
-
-void FSFloaterSearch::onBtnGroupChat()
-{
-    LLGroupActions::startIM(getSelectedID());
-}
-
-void FSFloaterSearch::onBtnGroupJoin()
-{
-    LLGroupActions::join(getSelectedID());
-}
-
-void FSFloaterSearch::onBtnTeleport()
-{
-    if (!mParcelGlobal.isExactlyZero())
-    {
-        gAgent.teleportViaLocation(mParcelGlobal);
-        LLFloaterWorldMap::getInstance()->trackLocation(mParcelGlobal);
-        /// <FS:CR> What should we do when when we teleport? The default (1) is to close the floater,
-        /// the user may elect to minimize the floater (2), or to do nothing (any other setting)
-        static LLCachedControl<U32> teleport_action(gSavedSettings, "FSLegacySearchActionOnTeleport");
-        if (teleport_action == 1)
-        {
-            closeFloater();
-        }
-        else if (teleport_action == 2)
-        {
-            setMinimized(TRUE);
-        }
-    }
-}
-
-void FSFloaterSearch::onBtnMap()
-{
-    if (!mParcelGlobal.isExactlyZero())
-    {
-        LLFloaterWorldMap::getInstance()->trackLocation(mParcelGlobal);
-        LLFloaterReg::showInstance("world_map", "center");
-    }
-}
-
-void FSFloaterSearch::onBtnEventReminder()
-{
-    gEventNotifier.add(mEventID);
-}
-
-////////////////////////////////////////
-//         People Search Panel        //
-////////////////////////////////////////
-
-static LLPanelInjector<FSPanelSearchPeople> t_panel_fs_search_people("panel_ls_people");
-
-FSPanelSearchPeople::FSPanelSearchPeople() : FSSearchPanelBase()
-, mQueryID(nullptr)
-, mStartSearch(0)
-, mResultsReceived(0)
-, mResultsContent()
-, mAvatarNameCallbackConnection()
-{
-}
-
-FSPanelSearchPeople::~FSPanelSearchPeople()
-{
-    if (mAvatarNameCallbackConnection.connected())
-    {
-        mAvatarNameCallbackConnection.disconnect();
-    }
-}
-
-BOOL FSPanelSearchPeople::postBuild()
-{
-    mSearchComboBox =   findChild<LLSearchComboBox>("people_edit");
-    mSearchResults =    findChild<LLScrollListCtrl>("search_results_people");
-    if (mSearchComboBox)
-    {
-        mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchPeople::onBtnFind, this));
-        fillSearchComboBox(mSearchComboBox);
-    }
-    if (mSearchResults)
-    {
-        mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchPeople::onSelectItem, this));
-        mSearchResults->setEnabled(FALSE);
-        mSearchResults->setCommentText(LLTrans::getString("no_results"));
-        mSearchResults->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
-    }
-
-    childSetAction("people_next", boost::bind(&FSPanelSearchPeople::onBtnNext, this));
-    childSetAction("people_back", boost::bind(&FSPanelSearchPeople::onBtnBack, this));
-    getChildView("people_next")->setEnabled(FALSE);
-    getChildView("people_back")->setEnabled(FALSE);
-
-    return TRUE;
-}
-
-void FSPanelSearchPeople::focusDefaultElement()
-{
-    mSearchComboBox->focusTextEntry();
-}
-
-void FSPanelSearchPeople::find()
-{
-    std::string text = mSearchComboBox->getSimple();
-    boost::trim(text);
-    if (text.size() <= MIN_SEARCH_STRING_SIZE)
-    {
-        mSearchResults->setCommentText(LLTrans::getString("search_short"));
-        return;
-    }
-
-    if (LLUUID::validate(text))
-    {
-        LLUUID id(text);
-
-        mSearchResults->deleteAllItems();
-        mSearchResults->setCommentText(LLTrans::getString("searching"));
-        mResultsReceived = 0;
-        mNumResultsReturned = 0;
-
-        if (mAvatarNameCallbackConnection.connected())
-        {
-            mAvatarNameCallbackConnection.disconnect();
-        }
-        mAvatarNameCallbackConnection = LLAvatarNameCache::get(id, boost::bind(&FSPanelSearchPeople::onAvatarNameCallback, this, _1, _2));
-
-        return;
-    }
-
-    LLStringUtil::replaceChar(text, '.', ' ');
-
-    mResultsReceived = 0;
-    if (mQueryID.notNull())
-    {
-        mQueryID.setNull();
-    }
-    mQueryID.generate();
-
-    if (mStartSearch < 0)
-    {
-        mStartSearch = 0;
-    }
-
-    gMessageSystem->newMessage("DirFindQuery");
-    gMessageSystem->nextBlock("AgentData");
-    gMessageSystem->addUUID("AgentID", gAgentID);
-    gMessageSystem->addUUID("SessionID", gAgentSessionID);
-    gMessageSystem->nextBlock("QueryData");
-    gMessageSystem->addUUID("QueryID", getQueryID());
-    gMessageSystem->addString("QueryText", text);
-    gMessageSystem->addU32("QueryFlags", DFQ_PEOPLE);
-    gMessageSystem->addS32("QueryStart", mStartSearch);
-    gAgent.sendReliableMessage();
-    LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << LL_ENDL;
-
-    mSearchResults->deleteAllItems();
-    mSearchResults->setCommentText(LLTrans::getString("searching"));
-    mNumResultsReturned = 0;
-}
-
-void FSPanelSearchPeople::onBtnFind()
-{
-    std::string text = mSearchComboBox->getSimple();
-    if (!text.empty())
-    {
-        LLSearchHistory::getInstance()->addEntry(text);
-    }
-
-    resetSearch();
-
-    find();
-}
-
-void FSPanelSearchPeople::onBtnNext()
-{
-    mStartSearch += RESULT_PAGE_SIZE;
-    getChildView("people_back")->setEnabled(TRUE);
-
-    find();
-}
-
-void FSPanelSearchPeople::onBtnBack()
-{
-    mStartSearch -= RESULT_PAGE_SIZE;
-    getChildView("people_back")->setEnabled(mStartSearch > 0);
-
-    find();
-}
-
-void FSPanelSearchPeople::resetSearch()
-{
-    mStartSearch = 0;
-    getChildView("people_back")->setEnabled(FALSE);
-    getChildView("people_next")->setEnabled(FALSE);
-}
-
-S32 FSPanelSearchPeople::showNextButton(S32 rows)
-{
-    bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE);
-    getChildView("people_next")->setEnabled(show_next_button);
-    if (show_next_button)
-    {
-        rows -= (mResultsReceived - RESULT_PAGE_SIZE);
-    }
-    return rows;
-}
-
-void FSPanelSearchPeople::onSelectItem()
-{
-    if (!mSearchResults)
-    {
-        return;
-    }
-    FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search");
-    if (search_instance)
-    {
-        search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_AVATAR);
-    }
-}
-
-// static
-void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**)
-{
-    LLUUID query_id;
-    std::string first_name;
-    std::string last_name;
-    LLUUID agent_id;
-
-    msg->getUUIDFast(_PREHASH_QueryData,    _PREHASH_QueryID,   query_id);
-    msg->getUUIDFast(_PREHASH_AgentData,    _PREHASH_AgentID,   agent_id);
-
-    // This result is not for us.
-    if (agent_id != gAgentID)
-    {
-        return;
-    }
-    LL_DEBUGS("Search") << "received search results - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL;
-
-    FSPanelSearchPeople* self = FSFloaterSearch::getSearchPanel<FSPanelSearchPeople>("panel_ls_people");
-
-    // floater is closed or these are not results from our last request
-    if (!self || query_id != self->getQueryID())
-    {
-        return;
-    }
-
-    LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_people");
-
-    if (self->mNumResultsReturned++ == 0)
-    {
-        search_results->deleteAllItems();
-    }
-
-    // Check for status messages
-    if (msg->getNumberOfBlocks("StatusData"))
-    {
-        U32 status;
-        msg->getU32("StatusData", "Status", status);
-        if (status & STATUS_SEARCH_PLACES_FOUNDNONE)
-        {
-            LLStringUtil::format_map_t map;
-            map["[TEXT]"] = self->getChild<LLUICtrl>("people_edit")->getValue().asString();
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("not_found", map));
-            return;
-        }
-        else if (status & STATUS_SEARCH_PLACES_SHORTSTRING)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_short"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_PLACES_BANNEDWORD)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_banned"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_disabled"));
-            return;
-        }
-    }
-
-    bool found_one = false;
-    S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
-    if (num_new_rows == 0 && self->mResultsReceived == 0)
-    {
-        LLStringUtil::format_map_t map;
-        map["[TEXT]"] = self->getChild<LLUICtrl>("people_edit")->getValue().asString();
-        search_results->setEnabled(FALSE);
-        search_results->setCommentText(LLTrans::getString("not_found", map));
-    }
-
-    self->mResultsReceived += num_new_rows;
-    num_new_rows = self->showNextButton(num_new_rows);
-
-    for (S32 i = 0; i < num_new_rows; i++)
-    {
-        msg->getStringFast( _PREHASH_QueryReplies,  _PREHASH_FirstName, first_name, i);
-        msg->getStringFast( _PREHASH_QueryReplies,  _PREHASH_LastName,  last_name, i);
-        msg->getUUIDFast(   _PREHASH_QueryReplies,  _PREHASH_AgentID,   agent_id, i);
-        //msg->getU8Fast(   _PREHASH_QueryReplies,  _PREHASH_Online,    online, i);
-
-        if (agent_id.isNull())
-        {
-            LL_INFOS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL;
-            LLStringUtil::format_map_t map;
-            map["[TEXT]"] = self->getChild<LLUICtrl>("people_edit")->getValue().asString();
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("not_found", map));
-        }
-        else
-        {
-            LL_DEBUGS("Search") << "Got: " << first_name << " " << last_name << " AgentID: " << agent_id << LL_ENDL;
-            search_results->setEnabled(TRUE);
-            found_one = true;
-
-            std::string avatar_name;
-            avatar_name = LLCacheName::buildFullName(first_name, last_name);
-
-            LLSD content;
-            LLSD element;
-
-            element["id"] = agent_id;
-
-            element["columns"][0]["column"] = "icon";
-            element["columns"][0]["type"]   = "icon";
-            element["columns"][0]["value"]  = "icon_avatar_offline.tga";
-
-            element["columns"][1]["column"] = "username";
-            element["columns"][1]["value"]  = avatar_name;
-
-            content["name"] = avatar_name;
-
-            search_results->addElement(element, ADD_BOTTOM);
-            self->mResultsContent[agent_id.asString()] = content;
-        }
-    }
-    if (found_one)
-    {
-        search_results->selectFirstItem();
-        search_results->setFocus(TRUE);
-        self->onSelectItem();
-    }
-}
-
-void FSPanelSearchPeople::onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name)
-{
-    if (mAvatarNameCallbackConnection.connected())
-    {
-        mAvatarNameCallbackConnection.disconnect();
-    }
-
-    LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("search_results_people");
-
-    if (av_name.getAccountName() != "(?\?\?).(?\?\?)")
-    {
-        LLSD content;
-        LLSD data;
-        data["id"] = id;
-
-        data["columns"][0]["column"] = "icon";
-        data["columns"][0]["type"] = "icon";
-        data["columns"][0]["value"] = "icon_avatar_offline.tga";
-
-        data["columns"][1]["name"] = "username";
-        data["columns"][1]["value"] = av_name.getUserName();
-
-        content["name"] = av_name.getUserName();
-
-        search_results->addElement(data);
-
-        mResultsContent[id.asString()] = content;
-        mResultsReceived = 1;
-        mNumResultsReturned = 1;
-
-        search_results->setEnabled(TRUE);
-        search_results->selectFirstItem();
-        search_results->setFocus(TRUE);
-        onSelectItem();
-    }
-    else
-    {
-        LLStringUtil::format_map_t map;
-        map["[TEXT]"] = getChild<LLUICtrl>("people_edit")->getValue().asString();
-        search_results->setEnabled(FALSE);
-        search_results->setCommentText(LLTrans::getString("not_found", map));
-    }
-}
-
-////////////////////////////////////////
-//         Groups Search Panel        //
-////////////////////////////////////////
-
-static LLPanelInjector<FSPanelSearchGroups> t_panel_fs_search_groups("panel_ls_groups");
-
-FSPanelSearchGroups::FSPanelSearchGroups() : FSSearchPanelBase()
-, mQueryID(nullptr)
-, mStartSearch(0)
-, mResultsReceived(0)
-, mResultsContent()
-{
-}
-
-FSPanelSearchGroups::~FSPanelSearchGroups()
-{
-}
-
-BOOL FSPanelSearchGroups::postBuild()
-{
-    mSearchComboBox =   findChild<LLSearchComboBox>("groups_edit");
-    mSearchResults =    findChild<LLScrollListCtrl>("search_results_groups");
-    if (mSearchComboBox)
-    {
-        mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchGroups::onBtnFind, this));
-        fillSearchComboBox(mSearchComboBox);
-    }
-    if (mSearchResults)
-    {
-        mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchGroups::onSelectItem, this));
-        mSearchResults->setEnabled(FALSE);
-        mSearchResults->setCommentText(LLTrans::getString("no_results"));
-    }
-
-    childSetAction("groups_next", boost::bind(&FSPanelSearchGroups::onBtnNext, this));
-    childSetAction("groups_back", boost::bind(&FSPanelSearchGroups::onBtnBack, this));
-    getChildView("groups_next")->setEnabled(FALSE);
-    getChildView("groups_back")->setEnabled(FALSE);
-
-    return TRUE;
-}
-
-void FSPanelSearchGroups::focusDefaultElement()
-{
-    mSearchComboBox->focusTextEntry();
-}
-
-void FSPanelSearchGroups::find()
-{
-    std::string text = filterShortWords(mSearchComboBox->getSimple());
-    if (text.size() == 0)
-    {
-        mSearchResults->setCommentText(LLTrans::getString("search_short"));
-        return;
-    }
-
-    static LLUICachedControl<bool> inc_pg("ShowPGSims", 1);
-    static LLUICachedControl<bool> inc_mature("ShowMatureSims", 0);
-    static LLUICachedControl<bool> inc_adult("ShowAdultSims", 0);
-    if (!(inc_pg || inc_mature || inc_adult))
-    {
-        LLNotificationsUtil::add("NoContentToSearch");
-        return;
-    }
-    U32 scope = 0;
-    if (gAgent.wantsPGOnly())
-    {
-        scope |= DFQ_PG_SIMS_ONLY;
-    }
-    bool adult_enabled = gAgent.canAccessAdult();
-    bool mature_enabled = gAgent.canAccessMature();
-    if (inc_pg)
-    {
-        scope |= DFQ_INC_PG;
-    }
-    if (inc_mature && mature_enabled)
-    {
-        scope |= DFQ_INC_MATURE;
-    }
-    if (inc_adult && adult_enabled)
-    {
-        scope |= DFQ_INC_ADULT;
-    }
-    scope |= DFQ_GROUPS;
-
-    mResultsReceived = 0;
-    if (mQueryID.notNull())
-    {
-        mQueryID.setNull();
-    }
-    mQueryID.generate();
-
-    if (mStartSearch < 0)
-    {
-        mStartSearch = 0;
-    }
-
-    gMessageSystem->newMessage("DirFindQuery");
-    gMessageSystem->nextBlock("AgentData");
-    gMessageSystem->addUUID("AgentID", gAgentID);
-    gMessageSystem->addUUID("SessionID", gAgentSessionID);
-    gMessageSystem->nextBlock("QueryData");
-    gMessageSystem->addUUID("QueryID", getQueryID());
-    gMessageSystem->addString("QueryText", text);
-    gMessageSystem->addU32("QueryFlags", scope);
-    gMessageSystem->addS32("QueryStart", mStartSearch);
-    gAgent.sendReliableMessage();
-    LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << LL_ENDL;
-
-    mSearchResults->deleteAllItems();
-    mSearchResults->setCommentText(LLTrans::getString("searching"));
-    mNumResultsReturned = 0;
-}
-
-void FSPanelSearchGroups::onBtnFind()
-{
-    std::string text = mSearchComboBox->getSimple();
-    if (!text.empty())
-    {
-        LLSearchHistory::getInstance()->addEntry(text);
-    }
-
-    resetSearch();
-
-    find();
-}
-
-void FSPanelSearchGroups::onBtnNext()
-{
-    mStartSearch += RESULT_PAGE_SIZE;
-    getChildView("groups_back")->setEnabled(TRUE);
-
-    find();
-}
-
-void FSPanelSearchGroups::onBtnBack()
-{
-    mStartSearch -= RESULT_PAGE_SIZE;
-    getChildView("groups_back")->setEnabled(mStartSearch > 0);
-
-    find();
-}
-
-void FSPanelSearchGroups::resetSearch()
-{
-    mStartSearch = 0;
-    getChildView("groups_back")->setEnabled(FALSE);
-    getChildView("groups_next")->setEnabled(FALSE);
-}
-
-S32 FSPanelSearchGroups::showNextButton(S32 rows)
-{
-    bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE);
-    getChildView("groups_next")->setEnabled(show_next_button);
-    if (show_next_button)
-    {
-        rows -= (mResultsReceived - RESULT_PAGE_SIZE);
-    }
-    return rows;
-}
-
-void FSPanelSearchGroups::onSelectItem()
-{
-    if (!mSearchResults)
-    {
-        return;
-    }
-    FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search");
-    if (search_instance)
-    {
-        search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_GROUP);
-    }
-}
-
-// static
-void FSPanelSearchGroups::processSearchReply(LLMessageSystem* msg, void**)
-{
-    LLUUID query_id;
-    LLUUID group_id;
-    LLUUID agent_id;
-    std::string group_name;
-    S32 members;
-    F32 search_order;
-
-    msg->getUUIDFast(   _PREHASH_QueryData, _PREHASH_QueryID,   query_id);
-    msg->getUUIDFast(   _PREHASH_AgentData, _PREHASH_AgentID,   agent_id);
-
-    // Not for us
-    if (agent_id != gAgentID)
-    {
-        return;
-    }
-    LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL;
-
-    FSPanelSearchGroups* self = FSFloaterSearch::getSearchPanel<FSPanelSearchGroups>("panel_ls_groups");
-
-    // floater is closed or these are not results from our last request
-    if (!self || query_id != self->mQueryID)
-    {
-        return;
-    }
-
-    LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_groups");
-
-    // Clear "Searching" label on first results
-    if (self->mNumResultsReturned++ == 0)
-    {
-        search_results->deleteAllItems();
-    }
-
-    // Check for status messages
-    if (msg->getNumberOfBlocks("StatusData"))
-    {
-        U32 status;
-        msg->getU32("StatusData", "Status", status);
-        if (status & STATUS_SEARCH_PLACES_FOUNDNONE)
-        {
-            LLStringUtil::format_map_t map;
-            map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString();
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("not_found", map));
-            return;
-        }
-        else if(status & STATUS_SEARCH_PLACES_SHORTSTRING)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_short"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_PLACES_BANNEDWORD)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_banned"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_disabled"));
-            return;
-        }
-    }
-
-    bool found_one = false;
-    S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
-    if (num_new_rows == 0 && self->mResultsReceived == 0)
-    {
-        LLStringUtil::format_map_t map;
-        map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString();
-        search_results->setEnabled(FALSE);
-        search_results->setCommentText(LLTrans::getString("not_found", map));
-    }
-
-    self->mResultsReceived += num_new_rows;
-    num_new_rows = self->showNextButton(num_new_rows);
-
-    for (S32 i = 0; i < num_new_rows; i++)
-    {
-        msg->getUUIDFast(   _PREHASH_QueryReplies,  _PREHASH_GroupID,       group_id,   i);
-        msg->getStringFast( _PREHASH_QueryReplies,  _PREHASH_GroupName,     group_name, i);
-        msg->getS32Fast(    _PREHASH_QueryReplies,  _PREHASH_Members,       members,    i);
-        msg->getF32Fast(    _PREHASH_QueryReplies,  _PREHASH_SearchOrder,   search_order,i);
-        if (group_id.isNull())
-        {
-            LL_DEBUGS("Search") << "No results returned for QueryID: " << query_id << LL_ENDL;
-            LLStringUtil::format_map_t map;
-            map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString();
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("not_found", map));
-        }
-        else
-        {
-            LL_DEBUGS("Search") << "Got: " << group_name << " GroupID: " << group_id << LL_ENDL;
-            search_results->setEnabled(TRUE);
-            found_one = true;
-
-            LLSD content;
-            LLSD element;
-
-            element["id"] = group_id;
-
-            element["columns"][0]["column"] = "icon";
-            element["columns"][0]["type"]   = "icon";
-            element["columns"][0]["value"]  = "Icon_Group";
-
-            element["columns"][1]["column"] = "group_name";
-            element["columns"][1]["value"]  = group_name;
-
-            element["columns"][2]["column"] = "members";
-            element["columns"][2]["value"]  = members;
-
-            element["columns"][3]["column"] = "score";
-            element["columns"][3]["value"]  = search_order;
-
-            content["name"] = group_name;
-
-            search_results->addElement(element, ADD_BOTTOM);
-            self->mResultsContent[group_id.asString()] = content;
-        }
-    }
-    if (found_one)
-    {
-        search_results->selectFirstItem();
-        search_results->setFocus(TRUE);
-        self->onSelectItem();
-    }
-}
-
-////////////////////////////////////////
-//         Places Search Panel        //
-////////////////////////////////////////
-
-static LLPanelInjector<FSPanelSearchPlaces> t_panel_fs_search_places("panel_ls_places");
-
-FSPanelSearchPlaces::FSPanelSearchPlaces() : FSSearchPanelBase()
-, mQueryID(nullptr)
-, mStartSearch(0)
-, mResultsReceived(0)
-, mResultsContent()
-{
-    mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchPlaces::find, this));
-}
-
-FSPanelSearchPlaces::~FSPanelSearchPlaces()
-{
-}
-
-BOOL FSPanelSearchPlaces::postBuild()
-{
-    mSearchComboBox =   findChild<LLSearchComboBox>("places_edit");
-    mSearchResults =    findChild<LLScrollListCtrl>("search_results_places");
-    mPlacesCategory =   findChild<LLComboBox>("places_category");
-    if (mSearchComboBox)
-    {
-        mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchPlaces::onBtnFind, this));
-        fillSearchComboBox(mSearchComboBox);
-    }
-    if (mSearchResults)
-    {
-        mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchPlaces::onSelectItem, this));
-        mSearchResults->setEnabled(FALSE);
-        mSearchResults->setCommentText(LLTrans::getString("no_results"));
-    }
-    if (mPlacesCategory)
-    {
-        mPlacesCategory->add(LLTrans::getString("all_categories"), LLSD("any"));
-        mPlacesCategory->addSeparator();
-        for (int category = LLParcel::C_LINDEN; category < LLParcel::C_COUNT; category++)
-        {
-            LLParcel::ECategory eCategory = (LLParcel::ECategory)category;
-            mPlacesCategory->add(LLTrans::getString(LLParcel::getCategoryUIString(eCategory)), LLParcel::getCategoryString(eCategory));
-        }
-    }
-    childSetAction("places_next", boost::bind(&FSPanelSearchPlaces::onBtnNext, this));
-    childSetAction("places_back", boost::bind(&FSPanelSearchPlaces::onBtnBack, this));
-    getChildView("places_next")->setEnabled(FALSE);
-    getChildView("places_back")->setEnabled(FALSE);
-
-    return TRUE;
-}
-
-void FSPanelSearchPlaces::focusDefaultElement()
-{
-    mSearchComboBox->focusTextEntry();
-}
-
-void FSPanelSearchPlaces::find()
-{
-    std::string text = filterShortWords(mSearchComboBox->getSimple());
-    if (text.empty())
-    {
-        mSearchResults->setCommentText(LLTrans::getString("search_short"));
-        return;
-    }
-
-    static LLUICachedControl<bool> inc_pg("ShowPGSims", 1);
-    static LLUICachedControl<bool> inc_mature("ShowMatureSims", 0);
-    static LLUICachedControl<bool> inc_adult("ShowAdultSims", 0);
-    if (!(inc_pg || inc_mature || inc_adult))
-    {
-        LLNotificationsUtil::add("NoContentToSearch");
-        return;
-    }
-    S8 category;
-    std::string category_string = mPlacesCategory->getSelectedValue();
-    if (category_string == "any")
-    {
-        category = LLParcel::C_ANY;
-    }
-    else
-    {
-        category = LLParcel::getCategoryFromString(category_string);
-    }
-    U32 scope = 0;
-    if (gAgent.wantsPGOnly())
-    {
-        scope |= DFQ_PG_SIMS_ONLY;
-    }
-    bool adult_enabled = gAgent.canAccessAdult();
-    bool mature_enabled = gAgent.canAccessMature();
-    if (inc_pg)
-    {
-        scope |= DFQ_INC_PG;
-    }
-    if (inc_mature && mature_enabled)
-    {
-        scope |= DFQ_INC_MATURE;
-    }
-    if (inc_adult && adult_enabled)
-    {
-        scope |= DFQ_INC_ADULT;
-    }
-    scope |= DFQ_DWELL_SORT;
-
-    mResultsReceived = 0;
-    if (mQueryID.notNull())
-    {
-        mQueryID.setNull();
-    }
-    mQueryID.generate();
-
-    if (mStartSearch < 0)
-    {
-        mStartSearch = 0;
-    }
-
-    gMessageSystem->newMessage("DirPlacesQuery");
-    gMessageSystem->nextBlock("AgentData");
-    gMessageSystem->addUUID("AgentID", gAgentID);
-    gMessageSystem->addUUID("SessionID", gAgentSessionID);
-    gMessageSystem->nextBlock("QueryData");
-    gMessageSystem->addUUID("QueryID", getQueryID());
-    gMessageSystem->addString("QueryText", text);
-    gMessageSystem->addU32("QueryFlags", scope);
-    gMessageSystem->addS8("Category", category);
-    // TODO: Search filter by region name.
-    gMessageSystem->addString("SimName", "");
-    gMessageSystem->addS32("QueryStart", mStartSearch);
-    gAgent.sendReliableMessage();
-    LL_DEBUGS("Search") << "Firing off places search request: " << getQueryID() << LL_ENDL;
-
-    mSearchResults->deleteAllItems();
-    mSearchResults->setCommentText(LLTrans::getString("searching"));
-    mNumResultsReturned = 0;
-}
-
-void FSPanelSearchPlaces::onBtnFind()
-{
-    std::string text = mSearchComboBox->getSimple();
-    if (!text.empty())
-    {
-        LLSearchHistory::getInstance()->addEntry(text);
-    }
-
-    resetSearch();
-
-    find();
-}
-
-void FSPanelSearchPlaces::onBtnNext()
-{
-    mStartSearch += RESULT_PAGE_SIZE;
-    getChildView("places_back")->setEnabled(TRUE);
-
-    find();
-}
-
-void FSPanelSearchPlaces::onBtnBack()
-{
-    mStartSearch -= RESULT_PAGE_SIZE;
-    getChildView("places_back")->setEnabled(mStartSearch > 0);
-
-    find();
-}
-
-void FSPanelSearchPlaces::resetSearch()
-{
-    mStartSearch = 0;
-    getChildView("places_back")->setEnabled(FALSE);
-    getChildView("places_next")->setEnabled(FALSE);
-}
-
-S32 FSPanelSearchPlaces::showNextButton(S32 rows)
-{
-    bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE);
-    getChildView("places_next")->setEnabled(show_next_button);
-    if (show_next_button)
-    {
-        rows -= (mResultsReceived - RESULT_PAGE_SIZE);
-    }
-    return rows;
-}
-
-void FSPanelSearchPlaces::onSelectItem()
-{
-    if (!mSearchResults)
-    {
-        return;
-    }
-    FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search");
-    if (search_instance)
-    {
-        search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE);
-    }
-}
-
-// static
-void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**)
-{
-    LLUUID      agent_id;
-    LLUUID      query_id;
-    LLUUID      parcel_id;
-    std::string name;
-    BOOL        for_sale;
-    BOOL        auction;
-    F32         dwell;
-
-    msg->getUUID("AgentData", "AgentID", agent_id);
-    msg->getUUID("QueryData", "QueryID", query_id);
-
-    // Not for us
-    if (agent_id != gAgentID)
-    {
-        return;
-    }
-    LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL;
-
-    FSPanelSearchPlaces* self = FSFloaterSearch::getSearchPanel<FSPanelSearchPlaces>("panel_ls_places");
-
-    // floater is closed or these are not results from our last request
-    if (!self || query_id != self->getQueryID())
-    {
-        return;
-    }
-
-    LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_places");
-
-    // Clear "Searching" label on first results
-    if (self->mNumResultsReturned++ == 0)
-    {
-        search_results->deleteAllItems();
-    }
-
-    // Check for status messages
-    if (msg->getNumberOfBlocks("StatusData"))
-    {
-        U32 status;
-        msg->getU32("StatusData", "Status", status);
-        if (status & STATUS_SEARCH_PLACES_FOUNDNONE)
-        {
-            LLStringUtil::format_map_t map;
-            map["[TEXT]"] = self->getChild<LLUICtrl>("places_edit")->getValue().asString();
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("not_found", map));
-            return;
-        }
-        else if(status & STATUS_SEARCH_PLACES_SHORTSTRING)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_short"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_PLACES_BANNEDWORD)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_banned"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_disabled"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_PLACES_ESTATEEMPTY)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_disabled"));
-            return;
-        }
-    }
-
-    bool found_one = false;
-    S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies");
-    if (num_new_rows == 0 && self->mResultsReceived == 0)
-    {
-        LLStringUtil::format_map_t map;
-        map["[TEXT]"] = self->getChild<LLUICtrl>("places_edit")->getValue().asString();
-        search_results->setEnabled(FALSE);
-        search_results->setCommentText(LLTrans::getString("not_found", map));
-    }
-
-    self->mResultsReceived += num_new_rows;
-    num_new_rows = self->showNextButton(num_new_rows);
-
-    for (S32 i = 0; i < num_new_rows; i++)
-    {
-        msg->getUUID(   "QueryReplies", "ParcelID", parcel_id,  i);
-        msg->getString( "QueryReplies", "Name",     name,       i);
-        msg->getBOOL(   "QueryReplies", "ForSale",  for_sale,i);
-        msg->getBOOL(   "QueryReplies", "Auction",  auction,    i);
-        msg->getF32(    "QueryReplies", "Dwell",    dwell,      i);
-        if (parcel_id.isNull())
-        {
-            LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL;
-            LLStringUtil::format_map_t map;
-            map["[TEXT]"] = self->getChild<LLUICtrl>("places_edit")->getValue().asString();
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("not_found", map));
-        }
-        else
-        {
-            LL_DEBUGS("Search") << "Got: " << name << " ParcelID: " << parcel_id << LL_ENDL;
-            search_results->setEnabled(TRUE);
-            found_one = true;
-
-            LLSD content;
-            LLSD element;
-
-            element["id"] = parcel_id;
-
-            if (auction)
-            {
-                element["columns"][0]["column"] = "icon";
-                element["columns"][0]["type"]   = "icon";
-                element["columns"][0]["value"]  = "Icon_Auction";
-            }
-            else if (for_sale)
-            {
-                element["columns"][0]["column"] = "icon";
-                element["columns"][0]["type"]   = "icon";
-                element["columns"][0]["value"]  = "Icon_For_Sale";
-            }
-            else
-            {
-                element["columns"][0]["column"] = "icon";
-                element["columns"][0]["type"]   = "icon";
-                element["columns"][0]["value"]  = "Icon_Place";
-            }
-
-            element["columns"][1]["column"] = "place_name";
-            element["columns"][1]["value"]  = name;
-
-            content["name"] = name;
-
-            std::string buffer = llformat("%.0f", (F64)dwell);
-            element["columns"][2]["column"] = "dwell";
-            element["columns"][2]["value"]  = buffer;
-
-            search_results->addElement(element, ADD_BOTTOM);
-            self->mResultsContent[parcel_id.asString()] = content;
-        }
-    }
-    if (found_one)
-    {
-        search_results->selectFirstItem();
-        search_results->setFocus(TRUE);
-        self->onSelectItem();
-    }
-}
-
-////////////////////////////////////////
-//          Land Search Panel         //
-////////////////////////////////////////
-
-static LLPanelInjector<FSPanelSearchLand> t_panel_fs_search_land("panel_ls_land");
-
-FSPanelSearchLand::FSPanelSearchLand() : FSSearchPanelBase()
-, mQueryID(nullptr)
-, mStartSearch(0)
-, mResultsReceived(0)
-, mResultsContent()
-{
-    mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchLand::find, this));
-}
-
-FSPanelSearchLand::~FSPanelSearchLand()
-{
-}
-
-BOOL FSPanelSearchLand::postBuild()
-{
-    mSearchResults  = getChild<LLScrollListCtrl>("search_results_land");
-    mPriceEditor    = findChild<LLLineEditor>("price_edit");
-    mAreaEditor     = findChild<LLLineEditor>("area_edit");
-    if (mSearchResults)
-    {
-        mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchLand::onSelectItem, this));
-        mSearchResults->setEnabled(FALSE);
-        mSearchResults->setCommentText(LLTrans::getString("no_results"));
-    }
-    if (mPriceEditor)
-    {
-        mPriceEditor->setCommitOnFocusLost(false);
-        mPriceEditor->setCommitCallback(boost::bind(&FSPanelSearchLand::onBtnFind, this));
-    }
-    if (mAreaEditor)
-    {
-        mAreaEditor->setCommitOnFocusLost(false);
-        mAreaEditor->setCommitCallback(boost::bind(&FSPanelSearchLand::find, this));
-    }
-    childSetAction("land_find", boost::bind(&FSPanelSearchLand::onBtnFind, this));
-    childSetAction("land_next", boost::bind(&FSPanelSearchLand::onBtnNext, this));
-    childSetAction("land_back", boost::bind(&FSPanelSearchLand::onBtnBack, this));
-
-    getChildView("land_next")->setEnabled(FALSE);
-    getChildView("land_back")->setEnabled(FALSE);
-
-    return TRUE;
-}
-
-void FSPanelSearchLand::find()
-{
-    static LLUICachedControl<bool> inc_pg("ShowPGLand", 1);
-    static LLUICachedControl<bool> inc_mature("ShowMatureLand", 0);
-    static LLUICachedControl<bool> inc_adult("ShowAdultLand", 0);
-    static LLUICachedControl<bool> limit_price("FindLandPrice", 1);
-    static LLUICachedControl<bool> limit_area("FindLandArea", 1);
-    if (!(inc_pg || inc_mature || inc_adult))
-    {
-        LLNotificationsUtil::add("NoContentToSearch");
-        return;
-    }
-
-    U32 category = ST_ALL;
-    const std::string& selection = findChild<LLComboBox>("land_category")->getSelectedValue().asString();
-    if (!selection.empty())
-    {
-        if (selection == "Auction")
-        {
-            category = ST_AUCTION;
-        }
-        else if (selection == "Mainland")
-        {
-            category = ST_MAINLAND;
-        }
-        else if (selection == "Estate")
-        {
-            category = ST_ESTATE;
-        }
-    }
-
-    U32 scope = 0;
-    if (gAgent.wantsPGOnly())
-    {
-        scope |= DFQ_PG_SIMS_ONLY;
-    }
-    bool mature_enabled = gAgent.canAccessMature();
-    bool adult_enabled = gAgent.canAccessAdult();
-    if (inc_pg)
-    {
-        scope |= DFQ_INC_PG;
-    }
-    if (inc_mature && mature_enabled)
-    {
-        scope |= DFQ_INC_MATURE;
-    }
-    if (inc_adult && adult_enabled)
-    {
-        scope |= DFQ_INC_ADULT;
-    }
-    const std::string& sort = findChild<LLComboBox>("land_sort_combo")->getSelectedValue().asString();
-    if (!sort.empty())
-    {
-        if (sort == "Name")
-        {
-            scope |= DFQ_NAME_SORT;
-        }
-        else if (sort == "Price")
-        {
-            scope |= DFQ_PRICE_SORT;
-        }
-        else if (sort == "PPM")
-        {
-            scope |= DFQ_PER_METER_SORT;
-        }
-        else if (sort == "Area")
-        {
-            scope |= DFQ_AREA_SORT;
-        }
-    }
-    else
-    {
-        scope |= DFQ_PRICE_SORT;
-    }
-    if (childGetValue("ascending_check").asBoolean())
-    {
-        scope |= DFQ_SORT_ASC;
-    }
-    if (limit_price)
-    {
-        scope |= DFQ_LIMIT_BY_PRICE;
-    }
-    if (limit_area)
-    {
-        scope |= DFQ_LIMIT_BY_AREA;
-    }
-    S32 price = childGetValue("edit_price").asInteger();
-    S32 area = childGetValue("edit_area").asInteger();
-
-    mResultsReceived = 0;
-    if (mQueryID.notNull())
-    {
-        mQueryID.setNull();
-    }
-    mQueryID.generate();
-
-    if (mStartSearch < 0)
-    {
-        mStartSearch = 0;
-    }
-
-    gMessageSystem->newMessage("DirLandQuery");
-    gMessageSystem->nextBlock("AgentData");
-    gMessageSystem->addUUID("AgentID", gAgentID);
-    gMessageSystem->addUUID("SessionID", gAgentSessionID);
-    gMessageSystem->nextBlock("QueryData");
-    gMessageSystem->addUUID("QueryID", getQueryID());
-    gMessageSystem->addU32("QueryFlags", scope);
-    gMessageSystem->addU32("SearchType", category);
-    gMessageSystem->addS32("Price", price);
-    gMessageSystem->addS32("Area", area);
-    gMessageSystem->addS32("QueryStart", mStartSearch);
-    gAgent.sendReliableMessage();
-    LL_DEBUGS("Search") << "Firing off places search request: " << getQueryID() << category << LL_ENDL;
-
-    mSearchResults->deleteAllItems();
-    mSearchResults->setCommentText(LLTrans::getString("searching"));
-    mNumResultsReturned = 0;
-}
-
-void FSPanelSearchLand::onBtnFind()
-{
-    resetSearch();
-
-    find();
-}
-
-void FSPanelSearchLand::onBtnNext()
-{
-    mStartSearch += RESULT_PAGE_SIZE;
-    getChildView("land_back")->setEnabled(TRUE);
-
-    find();
-}
-
-void FSPanelSearchLand::onBtnBack()
-{
-    mStartSearch -= RESULT_PAGE_SIZE;
-    getChildView("land_back")->setEnabled(mStartSearch > 0);
-
-    find();
-}
-
-void FSPanelSearchLand::resetSearch()
-{
-    mStartSearch = 0;
-    getChildView("land_back")->setEnabled(FALSE);
-    getChildView("land_next")->setEnabled(FALSE);
-}
-
-S32 FSPanelSearchLand::showNextButton(S32 rows)
-{
-    bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE);
-    getChildView("land_next")->setEnabled(show_next_button);
-    if (show_next_button)
-    {
-        rows -= (mResultsReceived - RESULT_PAGE_SIZE);
-    }
-    return rows;
-}
-
-void FSPanelSearchLand::onSelectItem()
-{
-    if (!mSearchResults)
-    {
-        return;
-    }
-    FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search");
-    if (search_instance)
-    {
-        search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE);
-    }
-}
-
-// static
-void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**)
-{
-    LLUUID      agent_id;
-    LLUUID      query_id;
-    LLUUID      parcel_id;
-    std::string name;
-    std::string land_sku;
-    std::string land_type;
-    BOOL        auction;
-    BOOL        for_sale;
-    S32         price;
-    S32         area;
-
-    msg->getUUID("AgentData", "AgentID", agent_id);
-    msg->getUUID("QueryData", "QueryID", query_id);
-
-    // Not for us
-    if (agent_id != gAgentID)
-    {
-        return;
-    }
-    LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL;
-
-    FSPanelSearchLand* self = FSFloaterSearch::getSearchPanel<FSPanelSearchLand>("panel_ls_land");
-
-    // floater is closed or these are not results from our last request
-    if (!self || query_id != self->mQueryID)
-    {
-        return;
-    }
-
-    LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_land");
-    // clear "Searching" label on first results
-    if (self->mNumResultsReturned++ == 0)
-    {
-        search_results->deleteAllItems();
-    }
-
-    static LLUICachedControl<bool> use_price("FindLandPrice", 1);
-    static LLUICachedControl<bool> use_area("FindLandArea", 1);
-    S32 limit_price = self->childGetValue("edit_price").asInteger();
-    S32 limit_area = self->childGetValue("edit_area").asInteger();
-
-    bool found_one = false;
-    S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies");
-    if (num_new_rows == 0 && self->mResultsReceived == 0)
-    {
-        LLStringUtil::format_map_t map;
-        map["[TEXT]"] = self->getChild<LLUICtrl>("events_edit")->getValue().asString();
-        search_results->setEnabled(FALSE);
-        search_results->setCommentText(LLTrans::getString("not_found", map));
-    }
-    self->mResultsReceived += num_new_rows;
-
-    S32 not_auction = 0;
-    for (S32 i = 0; i < num_new_rows; i++)
-    {
-        msg->getUUID(   "QueryReplies", "ParcelID",     parcel_id,  i);
-        msg->getString( "QueryReplies", "Name",         name,       i);
-        msg->getBOOL(   "QueryReplies", "Auction",      auction,    i);
-        msg->getBOOL(   "QueryReplies", "ForSale",      for_sale,   i);
-        msg->getS32(    "QueryReplies", "SalePrice",    price,      i);
-        msg->getS32(    "QueryReplies", "ActualArea",   area,       i);
-        if (parcel_id.isNull())
-        {
-            LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL;
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("no_results"));
-        }
-        else
-        {
-            LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << parcel_id << LL_ENDL;
-            search_results->setEnabled(TRUE);
-            found_one = true;
-            if (msg->getSizeFast(_PREHASH_QueryReplies, i, _PREHASH_ProductSKU) > 0)
-            {
-                msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_ProductSKU, land_sku, i);
-                land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku);
-            }
-            else
-            {
-                land_sku.clear();
-                land_type = LLTrans::getString("land_type_unknown");
-            }
-            if (parcel_id.isNull())
-            {
-                continue;
-            }
-            if (use_price && (price > limit_price))
-            {
-                continue;
-            }
-            if (use_area && (area < limit_area))
-            {
-                continue;
-            }
-
-            LLSD content;
-            LLSD element;
-
-            element["id"] = parcel_id;
-            if (auction)
-            {
-                element["columns"][0]["column"] = "icon";
-                element["columns"][0]["type"]   = "icon";
-                element["columns"][0]["value"]  = "Icon_Auction";
-            }
-            else if (for_sale)
-            {
-                element["columns"][0]["column"] = "icon";
-                element["columns"][0]["type"]   = "icon";
-                element["columns"][0]["value"]  = "Icon_For_Sale";
-            }
-            else
-            {
-                element["columns"][0]["column"] = "icon";
-                element["columns"][0]["type"]   = "icon";
-                element["columns"][0]["value"]  = "Icon_Place";
-            }
-
-            element["columns"][1]["column"] = "land_name";
-            element["columns"][1]["value"]  = name;
-
-            content["place_name"] = name;
-
-            std::string buffer = "Auction";
-            if (!auction)
-            {
-                buffer = llformat("%d", price);
-                not_auction++;
-            }
-            element["columns"][2]["column"] = "price";
-            element["columns"][2]["value"]  = price;
-
-            element["columns"][3]["column"] = "area";
-            element["columns"][3]["value"]  = area;
-            if (!auction)
-            {
-                F32 ppm;
-                if (area > 0)
-                {
-                    ppm = (F32)price / (F32)area;
-                }
-                else
-                {
-                    ppm = 0.f;
-                }
-                std::string ppm_buffer = llformat("%.1f", ppm);
-                element["columns"][4]["column"] = "ppm";
-                element["columns"][4]["value"] = ppm_buffer;
-            }
-            else
-            {
-                element["columns"][4]["column"] = "ppm";
-                element["columns"][4]["value"]  = "1.0";
-            }
-
-            element["columns"][5]["column"] = "land_type";
-            element["columns"][5]["value"]  = land_type;
-
-            search_results->addElement(element, ADD_BOTTOM);
-            self->mResultsContent[parcel_id.asString()] = content;
-        }
-        // We test against non-auction properties because they don't count towards the page limit.
-        self->showNextButton(not_auction);
-    }
-    if (found_one)
-    {
-        search_results->selectFirstItem();
-        search_results->setFocus(TRUE);
-        self->onSelectItem();
-    }
-}
-
-////////////////////////////////////////
-//      Classifieds Search Panel      //
-////////////////////////////////////////
-
-static LLPanelInjector<FSPanelSearchClassifieds> t_panel_fs_search_classifieds("panel_ls_classifieds");
-
-FSPanelSearchClassifieds::FSPanelSearchClassifieds() : FSSearchPanelBase()
-, mQueryID(nullptr)
-, mStartSearch(0)
-, mResultsReceived(0)
-, mResultsContent()
-{
-    mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchClassifieds::find, this));
-}
-
-FSPanelSearchClassifieds::~FSPanelSearchClassifieds()
-{
-}
-
-BOOL FSPanelSearchClassifieds::postBuild()
-{
-    mSearchComboBox = findChild<LLSearchComboBox>("classifieds_edit");
-    mSearchResults = getChild<LLScrollListCtrl>("search_results_classifieds");
-    if (mSearchComboBox)
-    {
-        mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchClassifieds::onBtnFind, this));
-        fillSearchComboBox(mSearchComboBox);
-    }
-    if (mSearchResults)
-    {
-        mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchClassifieds::onSelectItem, this));
-        mSearchResults->setEnabled(FALSE);
-        mSearchResults->setCommentText(LLTrans::getString("no_results"));
-    }
-
-    mClassifiedsCategory = getChild<LLComboBox>("classifieds_category");
-    if (mClassifiedsCategory)
-    {
-        LLClassifiedInfo::cat_map::iterator iter;
-        mClassifiedsCategory->add(LLTrans::getString("all_categories"), LLSD(0));
-        mClassifiedsCategory->addSeparator();
-        for (iter = LLClassifiedInfo::sCategories.begin();
-             iter != LLClassifiedInfo::sCategories.end();
-             iter++)
-        {
-            mClassifiedsCategory->add(LLTrans::getString(iter->second), LLSD((S32)iter->first));
-        }
-    }
-    childSetAction("classifieds_next", boost::bind(&FSPanelSearchClassifieds::onBtnNext, this));
-    childSetAction("classifieds_back", boost::bind(&FSPanelSearchClassifieds::onBtnBack, this));
-
-    getChildView("classifieds_next")->setEnabled(FALSE);
-    getChildView("classifieds_back")->setEnabled(FALSE);
-
-    return TRUE;
-}
-
-void FSPanelSearchClassifieds::focusDefaultElement()
-{
-    mSearchComboBox->focusTextEntry();
-}
-
-void FSPanelSearchClassifieds::find()
-{
-    std::string text = filterShortWords(mSearchComboBox->getSimple());
-    if (text.size() == 0)
-    {
-        mSearchResults->setCommentText(LLTrans::getString("search_short"));
-        return;
-    }
-
-    static LLUICachedControl<bool> inc_pg("ShowPGClassifieds", 1);
-    static LLUICachedControl<bool> inc_mature("ShowMatureClassifieds", 0);
-    static LLUICachedControl<bool> inc_adult("ShowAdultClassifieds", 0);
-    if (!(inc_pg || inc_mature || inc_adult))
-    {
-        LLNotificationsUtil::add("NoContentToSearch");
-        return;
-    }
-    U32 category = mClassifiedsCategory->getValue().asInteger();
-    BOOL auto_renew = FALSE;
-    U32 flags = pack_classified_flags_request(auto_renew, inc_pg, inc_mature, inc_adult);
-
-    mResultsReceived = 0;
-    if (mQueryID.notNull())
-    {
-        mQueryID.setNull();
-    }
-    mQueryID.generate();
-
-    if (mStartSearch < 0)
-    {
-        mStartSearch = 0;
-    }
-
-    gMessageSystem->newMessageFast(_PREHASH_DirClassifiedQuery);
-    gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-    gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID);
-    gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
-    gMessageSystem->nextBlockFast(_PREHASH_QueryData);
-    gMessageSystem->addUUIDFast(_PREHASH_QueryID, getQueryID());
-    gMessageSystem->addStringFast(_PREHASH_QueryText, text);
-    gMessageSystem->addU32Fast(_PREHASH_QueryFlags, flags);
-    gMessageSystem->addU32Fast(_PREHASH_Category, category);
-    gMessageSystem->addS32Fast(_PREHASH_QueryStart, mStartSearch);
-    gAgent.sendReliableMessage();
-    LL_DEBUGS("Search") << "Firing off classified ad search request: " << getQueryID() << LL_ENDL;
-
-    mSearchResults->deleteAllItems();
-    mSearchResults->setCommentText(LLTrans::getString("searching"));
-    mNumResultsReturned = 0;
-}
-
-void FSPanelSearchClassifieds::onBtnFind()
-{
-    std::string text = mSearchComboBox->getSimple();
-    if (!text.empty())
-    {
-        LLSearchHistory::getInstance()->addEntry(text);
-    }
-
-    resetSearch();
-
-    find();
-}
-
-void FSPanelSearchClassifieds::onBtnNext()
-{
-    mStartSearch += RESULT_PAGE_SIZE;
-    getChildView("classifieds_back")->setEnabled(TRUE);
-
-    find();
-}
-
-void FSPanelSearchClassifieds::onBtnBack()
-{
-    mStartSearch -= RESULT_PAGE_SIZE;
-    getChildView("classifieds_back")->setEnabled(mStartSearch > 0);
-
-    find();
-}
-
-void FSPanelSearchClassifieds::resetSearch()
-{
-    mStartSearch = 0;
-    getChildView("classifieds_back")->setEnabled(FALSE);
-    getChildView("classifieds_next")->setEnabled(FALSE);
-}
-
-S32 FSPanelSearchClassifieds::showNextButton(S32 rows)
-{
-    bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE);
-    getChildView("classifieds_next")->setEnabled(show_next_button);
-    if (show_next_button)
-    {
-        rows -= (mResultsReceived - RESULT_PAGE_SIZE);
-    }
-    return rows;
-}
-
-void FSPanelSearchClassifieds::onSelectItem()
-{
-    if (!mSearchResults)
-    {
-        return;
-    }
-    FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search");
-    if (search_instance)
-    {
-        search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_CLASSIFIED);
-    }
-}
-
-// static
-void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**)
-{
-    LLUUID      agent_id;
-    LLUUID      query_id;
-    LLUUID      classified_id;
-    std::string name;
-    U32         creation_date;
-    U32         expiration_date;
-    S32         price_for_listing;
-
-    msg->getUUID("AgentData", "AgentID", agent_id);
-    msg->getUUID("QueryData", "QueryID", query_id);
-
-    // Not for us
-    if (agent_id != gAgentID)
-    {
-        return;
-    }
-    LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL;
-
-    FSPanelSearchClassifieds* self = FSFloaterSearch::getSearchPanel<FSPanelSearchClassifieds>("panel_ls_classifieds");
-
-    if (msg->getNumberOfBlocks("StatusData"))
-    {
-        U32 status;
-        msg->getU32("StatusData", "Status", status);
-        if (status & STATUS_SEARCH_CLASSIFIEDS_BANNEDWORD)
-        {
-            LLNotificationsUtil::add("SearchWordBanned");
-        }
-    }
-
-    // floater is closed or these are not results from our last request
-    if (!self || query_id != self->mQueryID)
-    {
-        return;
-    }
-
-    LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_classifieds");
-
-    // Clear "Searching" label on first results
-    if (self->mNumResultsReturned++ == 0)
-    {
-        search_results->deleteAllItems();
-    }
-
-    // Check for status messages
-    if (msg->getNumberOfBlocks("StatusData"))
-    {
-        U32 status;
-        msg->getU32("StatusData", "Status", status);
-        if (status & STATUS_SEARCH_PLACES_FOUNDNONE)
-        {
-            LLStringUtil::format_map_t map;
-            map["[TEXT]"] = self->getChild<LLUICtrl>("classifieds_edit")->getValue().asString();
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("not_found", map));
-            return;
-        }
-        else if(status & STATUS_SEARCH_PLACES_SHORTSTRING)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_short"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_CLASSIFIEDS_BANNEDWORD)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_banned"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_disabled"));
-            return;
-        }
-    }
-
-    bool found_one = false;
-    S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies");
-    if (num_new_rows == 0 && self->mResultsReceived == 0)
-    {
-        LLStringUtil::format_map_t map;
-        map["[TEXT]"] = self->getChild<LLUICtrl>("classifieds_edit")->getValue().asString();
-        search_results->setEnabled(FALSE);
-        search_results->setCommentText(LLTrans::getString("not_found", map));
-    }
-    self->mResultsReceived += num_new_rows;
-    num_new_rows = self->showNextButton(num_new_rows);
-
-    for (S32 i = 0; i < num_new_rows; i++)
-    {
-        msg->getUUID(   "QueryReplies", "ClassifiedID",     classified_id,  i);
-        msg->getString( "QueryReplies", "Name",             name,           i);
-        msg->getU32(    "QueryReplies", "CreationDate",     creation_date,  i);
-        msg->getU32(    "QueryReplies", "ExpirationDate",   expiration_date,i);
-        msg->getS32(    "QueryReplies", "PriceForListing",  price_for_listing,i);
-        if (classified_id.isNull())
-        {
-            LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL;
-            LLStringUtil::format_map_t map;
-            map["[TEXT]"] = self->getChild<LLUICtrl>("classifieds_edit")->getValue().asString();
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("not_found", map));
-        }
-        else
-        {
-            LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << classified_id << LL_ENDL;
-            search_results->setEnabled(TRUE);
-            found_one = true;
-
-            LLSD content;
-            LLSD element;
-
-            element["id"] = classified_id;
-
-            element["columns"][0]["column"] = "icon";
-            element["columns"][0]["type"]   = "icon";
-            element["columns"][0]["value"]  = "icon_top_pick.tga";
-
-            element["columns"][1]["column"] = "classified_name";
-            element["columns"][1]["value"]  = name;
-
-            element["columns"][2]["column"] = "price";
-            element["columns"][2]["value"]  = price_for_listing;
-
-            content["name"] = name;
-
-            search_results->addElement(element, ADD_BOTTOM);
-            self->mResultsContent[classified_id.asString()] = content;
-        }
-    }
-    if (found_one)
-    {
-        search_results->selectFirstItem();
-        search_results->setFocus(TRUE);
-        self->onSelectItem();
-    }
-}
-
-////////////////////////////////////////
-//        Events Search Panel         //
-////////////////////////////////////////
-
-static LLPanelInjector<FSPanelSearchEvents> t_panel_fs_search_events("panel_ls_events");
-
-FSPanelSearchEvents::FSPanelSearchEvents() : FSSearchPanelBase()
-, mQueryID(nullptr)
-, mResultsReceived(0)
-, mStartSearch(0)
-, mDay(0)
-, mResultsContent()
-{
-    mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchEvents::find, this));
-}
-
-FSPanelSearchEvents::~FSPanelSearchEvents()
-{
-}
-
-BOOL FSPanelSearchEvents::postBuild()
-{
-    mSearchComboBox = findChild<LLSearchComboBox>("events_edit");
-    mSearchResults = getChild<LLScrollListCtrl>("search_results_events");
-    mEventsMode = findChild<LLRadioGroup>("events_search_mode");
-    if (mSearchComboBox)
-    {
-        mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchEvents::onBtnFind, this));
-        fillSearchComboBox(mSearchComboBox);
-    }
-    if (mSearchResults)
-    {
-        mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchEvents::onSelectItem, this));
-        mSearchResults->setEnabled(FALSE);
-        mSearchResults->setCommentText(LLTrans::getString("no_results"));
-    }
-    if (mEventsMode)
-    {
-        mEventsMode->setCommitCallback(boost::bind(&FSPanelSearchEvents::onSearchModeChanged, this));
-        mEventsMode->selectFirstItem();
-    }
-
-    childSetAction("events_next", boost::bind(&FSPanelSearchEvents::onBtnNext, this));
-    childSetAction("events_back", boost::bind(&FSPanelSearchEvents::onBtnBack, this));
-    childSetAction("events_tomorrow", boost::bind(&FSPanelSearchEvents::onBtnTomorrow, this));
-    childSetAction("events_yesterday", boost::bind(&FSPanelSearchEvents::onBtnYesterday, this));
-    childSetAction("events_today", boost::bind(&FSPanelSearchEvents::onBtnToday, this));
-
-    getChildView("events_next")->setEnabled(FALSE);
-    getChildView("events_back")->setEnabled(FALSE);
-    getChildView("events_tomorrow")->setEnabled(FALSE);
-    getChildView("events_yesterday")->setEnabled(FALSE);
-    getChildView("events_today")->setEnabled(FALSE);
-    setDay(0);
-
-    return TRUE;
-}
-
-void FSPanelSearchEvents::focusDefaultElement()
-{
-    mSearchComboBox->focusTextEntry();
-}
-
-void FSPanelSearchEvents::find()
-{
-    std::string text = filterShortWords(mSearchComboBox->getSimple());
-
-    static LLUICachedControl<bool> inc_pg("ShowPGEvents", 1);
-    static LLUICachedControl<bool> inc_mature("ShowMatureEvents", 0);
-    static LLUICachedControl<bool> inc_adult("ShowAdultEvents", 0);
-    if (!(inc_pg || inc_mature || inc_adult))
-    {
-        LLNotificationsUtil::add("NoContentToSearch");
-        return;
-    }
-
-    U32 category = findChild<LLComboBox>("events_category")->getSelectedValue().asInteger();
-    U32 scope = DFQ_DATE_EVENTS;
-    if (gAgent.wantsPGOnly())
-    {
-        scope |= DFQ_PG_SIMS_ONLY;
-    }
-    bool mature_enabled = gAgent.canAccessMature();
-    bool adult_enabled = gAgent.canAccessAdult();
-    if (inc_pg)
-    {
-        scope |= DFQ_INC_PG;
-    }
-    if (inc_mature && mature_enabled)
-    {
-        scope |= DFQ_INC_MATURE;
-    }
-    if (inc_adult && adult_enabled)
-    {
-        scope |= DFQ_INC_ADULT;
-    }
-
-    std::ostringstream string;
-
-    if ("current" == childGetValue("events_search_mode").asString())
-    {
-        string << "u|";
-    }
-    else
-    {
-        string << mDay << "|";
-    }
-    string << category << "|";
-    string << text;
-
-    mResultsReceived = 0;
-    if (mQueryID.notNull())
-    {
-        mQueryID.setNull();
-    }
-    mQueryID.generate();
-
-    if (mStartSearch < 0)
-    {
-        mStartSearch = 0;
-    }
-
-    gMessageSystem->newMessage("DirFindQuery");
-    gMessageSystem->nextBlock("AgentData");
-    gMessageSystem->addUUID("AgentID", gAgentID);
-    gMessageSystem->addUUID("SessionID", gAgentSessionID);
-    gMessageSystem->nextBlock("QueryData");
-    gMessageSystem->addUUID("QueryID", getQueryID());
-    gMessageSystem->addString("QueryText", string.str());
-    gMessageSystem->addU32("QueryFlags", scope);
-    gMessageSystem->addS32("QueryStart", mStartSearch);
-    gAgent.sendReliableMessage();
-    LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << " Search Text: " << string.str() << LL_ENDL;
-
-    mSearchResults->deleteAllItems();
-    mSearchResults->setCommentText(LLTrans::getString("searching"));
-    mNumResultsReturned = 0;
-}
-
-void FSPanelSearchEvents::onBtnFind()
-{
-    std::string text = mSearchComboBox->getSimple();
-    if (!text.empty())
-    {
-        LLSearchHistory::getInstance()->addEntry(text);
-    }
-
-    resetSearch();
-
-    find();
-}
-
-void FSPanelSearchEvents::onBtnNext()
-{
-    mStartSearch += RESULT_PAGE_SIZE;
-    getChildView("events_back")->setEnabled(TRUE);
-
-    find();
-}
-
-void FSPanelSearchEvents::onBtnBack()
-{
-    mStartSearch -= RESULT_PAGE_SIZE;
-    getChildView("events_back")->setEnabled(mStartSearch > 0);
-
-    find();
-}
-
-void FSPanelSearchEvents::onBtnTomorrow()
-{
-    resetSearch();
-    setDay(mDay + 1);
-
-    find();
-}
-
-void FSPanelSearchEvents::onBtnYesterday()
-{
-    resetSearch();
-    setDay(mDay - 1);
-
-    find();
-}
-
-void FSPanelSearchEvents::onBtnToday()
-{
-    resetSearch();
-    setDay(0);
-
-    find();
-}
-
-void FSPanelSearchEvents::resetSearch()
-{
-    mStartSearch = 0;
-    getChildView("events_back")->setEnabled(FALSE);
-    getChildView("events_next")->setEnabled(FALSE);
-}
-
-void FSPanelSearchEvents::onSearchModeChanged()
-{
-    if (mEventsMode->getValue().asString() == "current")
-    {
-        getChildView("events_yesterday")->setEnabled(FALSE);
-        getChildView("events_tomorrow")->setEnabled(FALSE);
-        getChildView("events_today")->setEnabled(FALSE);
-    }
-    else
-    {
-        getChildView("events_yesterday")->setEnabled(TRUE);
-        getChildView("events_tomorrow")->setEnabled(TRUE);
-        getChildView("events_today")->setEnabled(TRUE);
-    }
-}
-
-void FSPanelSearchEvents::setDay(S32 day)
-{
-    mDay = day;
-    struct tm* internal_time;
-
-    time_t utc = time_corrected();
-    utc += day * 24 * 60 * 60;
-    internal_time = utc_to_pacific_time(utc, is_daylight_savings());
-    std::string buffer = llformat("%d/%d", 1 + internal_time->tm_mon, internal_time->tm_mday);
-    childSetValue("events_date", buffer);
-}
-
-S32 FSPanelSearchEvents::showNextButton(S32 rows)
-{
-    bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE);
-    getChildView("events_next")->setEnabled(show_next_button);
-    if (show_next_button)
-    {
-        rows -= (mResultsReceived - RESULT_PAGE_SIZE);
-    }
-    return rows;
-}
-
-void FSPanelSearchEvents::onSelectItem()
-{
-    if (!mSearchResults)
-    {
-        return;
-    }
-    S32 event_id = mSearchResults->getSelectedValue();
-    FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search");
-    if (search_instance)
-    {
-        search_instance->FSFloaterSearch::onSelectedEvent(event_id);
-    }
-}
-
-// static
-void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**)
-{
-    LLUUID      agent_id;
-    LLUUID      query_id;
-    LLUUID      owner_id;
-    std::string name;
-    std::string date;
-
-    msg->getUUID("AgentData", "AgentID", agent_id);
-    msg->getUUID("QueryData", "QueryID", query_id);
-
-    // Not for us
-    if (agent_id != gAgentID)
-    {
-        return;
-    }
-    LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL;
-
-    FSPanelSearchEvents* self = FSFloaterSearch::getSearchPanel<FSPanelSearchEvents>("panel_ls_events");
-
-    // floater is closed or these are not results from our last request
-    if (!self || query_id != self->mQueryID)
-    {
-        return;
-    }
-
-    LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_events");
-
-    // Clear "Searching" label on first results
-    if (self->mNumResultsReturned++ == 0)
-    {
-        search_results->deleteAllItems();
-    }
-    // Check for status messages
-    if (msg->getNumberOfBlocks("StatusData"))
-    {
-        U32 status;
-        msg->getU32("StatusData", "Status", status);
-        if (status & STATUS_SEARCH_EVENTS_FOUNDNONE)
-        {
-            LLStringUtil::format_map_t map;
-            map["[TEXT]"] = self->getChild<LLUICtrl>("events_edit")->getValue().asString();
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("not_found", map));
-            return;
-        }
-        else if(status & STATUS_SEARCH_EVENTS_SHORTSTRING)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_short"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_EVENTS_BANNEDWORD)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_banned"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_EVENTS_SEARCHDISABLED)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_disabled"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_EVENTS_NODATEOFFSET)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_no_date_offset"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_EVENTS_NOCATEGORY)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_no_events_category"));
-            return;
-        }
-        else if (status & STATUS_SEARCH_EVENTS_NOQUERY)
-        {
-            search_results->setEnabled(FALSE);
-            search_results->setCommentText(LLTrans::getString("search_no_query"));
-            return;
-        }
-    }
-
-    S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies");
-    if (num_new_rows == 0 && self->mResultsReceived == 0)
-    {
-        LLStringUtil::format_map_t map;
-        map["[TEXT]"] = self->getChild<LLUICtrl>("events_edit")->getValue().asString();
-        search_results->setEnabled(FALSE);
-        search_results->setCommentText(LLTrans::getString("not_found", map));
-    }
-
-    self->mResultsReceived += num_new_rows;
-    num_new_rows = self->showNextButton(num_new_rows);
-    static LLUICachedControl<bool> inc_pg("ShowPGEvents", 1);
-    static LLUICachedControl<bool> inc_mature("ShowMatureEvents", 0);
-    static LLUICachedControl<bool> inc_adult("ShowAdultEvents", 0);
-    bool found_one = false;
-
-    for (S32 i = 0; i < num_new_rows; i++)
-    {
-        U32 event_id;
-        U32 unix_time;
-        U32 event_flags;
-
-        msg->getUUID(   "QueryReplies", "OwnerID",      owner_id,   i);
-        msg->getString( "QueryReplies", "Name",         name,       i);
-        msg->getU32(    "QueryReplies", "EventID",      event_id,   i);
-        msg->getString( "QueryReplies", "Date",         date,       i);
-        msg->getU32(    "QueryReplies", "UnixTime",     unix_time,  i);
-        msg->getU32(    "QueryReplies", "EventFlags",   event_flags,i);
-
-        // Skip empty events...
-        if (owner_id.isNull())
-        {
-            LL_INFOS("Search") << "Skipped " << event_id << " because of a nullptr owner result" << LL_ENDL;
-            continue;
-        }
-        // Skips events that don't match our scope...
-        if (((event_flags & (EVENT_FLAG_ADULT | EVENT_FLAG_MATURE)) == EVENT_FLAG_NONE) && !inc_pg)
-        {
-            LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL;
-            continue;
-        }
-        if ((event_flags & EVENT_FLAG_MATURE) && !inc_mature)
-        {
-            LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL;
-            continue;
-        }
-        if ((event_flags & EVENT_FLAG_ADULT) && !inc_adult)
-        {
-            LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL;
-            continue;
-        }
-        search_results->setEnabled(TRUE);
-        found_one = true;
-
-        LLSD content;
-        LLSD element;
-
-        element["id"] = llformat("%u", event_id);
-
-        if (event_flags == EVENT_FLAG_ADULT)
-        {
-            element["columns"][0]["column"] = "icon";
-            element["columns"][0]["type"] = "icon";
-            element["columns"][0]["value"] = "Icon_Legacy_Event_Adult";
-        }
-        else if (event_flags == EVENT_FLAG_MATURE)
-        {
-            element["columns"][0]["column"] = "icon";
-            element["columns"][0]["type"] = "icon";
-            element["columns"][0]["value"] = "Icon_Legacy_Event_Mature";
-        }
-        else
-        {
-            element["columns"][0]["column"] = "icon";
-            element["columns"][0]["type"] = "icon";
-            element["columns"][0]["value"] = "Icon_Legacy_Event_PG";
-        }
-        element["columns"][1]["column"] = "name";
-        element["columns"][1]["value"] = name;
-
-        element["columns"][2]["column"] = "date";
-        element["columns"][2]["value"] = date;
-
-        element["columns"][3]["column"] = "time";
-        element["columns"][3]["value"] = llformat("%u", unix_time);
-
-        content["name"] = name;
-        content["event_id"] = (S32)event_id;
-
-        search_results->addElement(element, ADD_BOTTOM);
-        std::string event = llformat("%u", event_id);
-        self->mResultsContent[event] = content;
-    }
-    if (found_one)
-    {
-        search_results->selectFirstItem();
-        search_results->setFocus(TRUE);
-        self->onSelectItem();
-    }
-}
-
-////////////////////////////////////////
-//          WebSearch Panel           //
-////////////////////////////////////////
-
-static LLPanelInjector<FSPanelSearchWeb> t_panel_fs_search_web("panel_ls_web");
-
-FSPanelSearchWeb::FSPanelSearchWeb() : FSSearchPanelBase()
-, mWebBrowser(nullptr)
-, mResetFocusOnLoad(false)
-{
-    // Second Life grids use a different URL format now
-    mCategoryPaths = LLSD::emptyMap();
-    if (LLGridManager::getInstance()->isInSecondlife())
-    {
-        // declare a map that transforms a category name into
-        // the parameter list that is used to search that category
-        mCategoryPaths["people"]       = "collection_chosen=people";
-        mCategoryPaths["places"]       = "collection_chosen=places";
-        mCategoryPaths["events"]       = "collection_chosen=events";
-        mCategoryPaths["groups"]       = "collection_chosen=groups";
-        mCategoryPaths["destinations"] = "collection_chosen=destinations";
-
-        mCategoryPaths["classifieds"]  = "search_type=classified";
-        mCategoryPaths["wiki"]         = "search/wiki";                     // not sure if this is still a thing in the new search
-
-        mCategoryPaths["all"]          = mCategoryPaths["people"].asString() + "&" +
-                                        mCategoryPaths["places"].asString() + "&" +
-                                        mCategoryPaths["events"].asString() + "&" +
-                                        mCategoryPaths["groups"].asString() + "&" +
-                                        mCategoryPaths["destinations"].asString();
-    }
-    // OpenSim currently still uses the old URL format
-    else
-    {
-        // declare a map that transforms a category name into
-        // the URL suffix that is used to search that category
-        mCategoryPaths["all"]          = "search";
-        mCategoryPaths["people"]       = "search/people";
-        mCategoryPaths["places"]       = "search/places";
-        mCategoryPaths["events"]       = "search/events";
-        mCategoryPaths["groups"]       = "search/groups";
-        mCategoryPaths["wiki"]         = "search/wiki";
-        mCategoryPaths["destinations"] = "destinations";
-        mCategoryPaths["classifieds"]  = "classifieds";
-    }
-}
-
-BOOL FSPanelSearchWeb::postBuild()
-{
-    mWebBrowser = getChild<LLMediaCtrl>("search_browser");
-    return TRUE;
-}
-
-void FSPanelSearchWeb::loadURL(const SearchQuery &p)
-{
-    if (!mWebBrowser || !p.validateBlock())
-    {
-        return;
-    }
-
-    // CATEGORY is no longer used as part of the path on Second Life grids
-    LLSD subs = LLSD().with("CATEGORY", "");
-
-    // on OpenSim grids it probably is currently still being used, so keep the old behavior
-    if (!LLGridManager::getInstance()->isInSecondlife())
-    {
-        // work out the subdir to use based on the requested category
-        LLSD subs = LLSD().with("CATEGORY", (mCategoryPaths.has(p.category.getValue()) ? mCategoryPaths[p.category.getValue()].asString() : mCategoryPaths["all"].asString()));
-    }
-
-    // add the search query string
-    subs["QUERY"] = LLURI::escape(p.query.getValue());
-
-    // add the permissions token that login.cgi gave us
-    // We use "search_token", and fallback to "auth_token" if not present.
-    LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token");
-    if (search_token.asString().empty())
-    {
-        search_token = LLLoginInstance::getInstance()->getResponse("auth_token");
-    }
-    subs["AUTH_TOKEN"] = search_token.asString();
-
-    // add the user's preferred maturity (can be changed via prefs)
-    std::string maturity;
-
-    // on Second Life grids, the maturity level is now a "&maturity" parameter that's not in the provided search URL
-    if (LLGridManager::getInstance()->isInSecondlife())
-    {
-        if (gAgent.prefersAdult())
-        {
-            maturity = "gma";  // PG,Mature,Adult
-        }
-        else if (gAgent.prefersMature())
-        {
-            maturity = "gm";  // PG,Mature
-        }
-        else
-        {
-            maturity = "g";  // PG
-        }
-
-        // not used on the SL search anymore, so clear out the respective parameter
-        subs["MATURITY"] = "";
-    }
-    // OpenSim probably still uses the old maturity variant, so keep the old behavior here
-    else
-    {
-        if (gAgent.prefersAdult())
-        {
-            maturity = "42";  // PG,Mature,Adult
-        }
-        else if (gAgent.prefersMature())
-        {
-            maturity = "21";  // PG,Mature
-        }
-        else
-        {
-            maturity = "13";  // PG
-        }
-        subs["MATURITY"] = maturity;
-    }
-
-    // add the user's god status
-    subs["GODLIKE"] = gAgent.isGodlike() ? "1" : "0";
-
-    // Get the search URL and expand all of the substitutions
-    // (also adds things like [LANGUAGE], [VERSION], [OS], etc.)
-
-    // add the maturity and category variables to the new Second Life search URL
-    std::string url = gAgent.getRegion() != nullptr ? gAgent.getRegion()->getSearchServerURL()
-        : gSavedSettings.getString(LLGridManager::getInstance()->isInOpenSim() ? "OpenSimSearchURL" : "SearchURL");
-    if (LLGridManager::getInstance()->isInSecondlife())
-    {
-        url.append("&maturity=" + maturity + "&" + mCategoryPaths[p.category.getValue()].asString());
-    }
-
-    url = LLWeb::expandURLSubstitutions(url, subs);
-
-    // Finally, load the URL in the webpanel
-    mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
-}
-
-void FSPanelSearchWeb::focusDefaultElement()
-{
-    mWebBrowser->setFocus(TRUE);
-}
-
-void FSPanelSearchWeb::draw()
-{
-    if (mResetFocusOnLoad)
-    {
-        focusDefaultElement();
-        mResetFocusOnLoad = false;
-    }
-
-    FSSearchPanelBase::draw();
-}
-
-////////////////////////////////////////
-//           Local functions          //
-////////////////////////////////////////
-
-std::string filterShortWords(std::string query_string)
-{
-    if (query_string.length() < 1)
-    {
-        return "";
-    }
-
-    std::string final_query;
-    bool filtered = false;
-    boost::char_separator<char> sep(" ");
-    boost::tokenizer<boost::char_separator<char> > tokens(query_string, sep);
-    boost::tokenizer<boost::char_separator<char> >::iterator iter = tokens.begin();
-    boost::tokenizer<boost::char_separator<char> >::iterator last = tokens.end();
-    boost::tokenizer<boost::char_separator<char> >::iterator temp;
-    for (; iter != last; ++iter)
-    {
-        if ((*iter).length() > MIN_SEARCH_STRING_SIZE)
-        {
-            final_query.append((*iter));
-            temp = iter; ++temp;
-            if (temp != last)
-            {
-                final_query.append(" ");
-            }
-        }
-        else
-        {
-            filtered = true;
-        }
-    }
-
-    if (filtered)
-    {
-        LLSD args = LLSD().with("FINALQUERY", final_query);
-        LLNotificationsUtil::add("SeachFilteredOnShortWords", args);
-    }
-
-    return final_query;
-}
-
-void fillSearchComboBox(LLSearchComboBox* search_combo)
-{
-    if (search_combo == nullptr)
-    {
-        return;
-    }
-
-    LLSearchHistory::getInstance()->load();
-
-    LLSearchHistory::search_history_list_t search_list =
-    LLSearchHistory::getInstance()->getSearchHistoryList();
-    LLSearchHistory::search_history_list_t::const_iterator it = search_list.begin();
-    for ( ; search_list.end() != it; ++it)
-    {
-        LLSearchHistory::LLSearchHistoryItem item = *it;
-        search_combo->add(item.search_query);
-    }
-}
diff --git a/indra/newview/fsfloatersearch.h b/indra/newview/fsfloatersearch.h
deleted file mode 100644
index 61cef8bab9847d5edb1db338e6e6cee776f6f732..0000000000000000000000000000000000000000
--- a/indra/newview/fsfloatersearch.h
+++ /dev/null
@@ -1,404 +0,0 @@
-/**
- * @file fsfloatersearch.h
- * @brief Firestorm search definitions
- *
- * $LicenseInfo:firstyear=2012&license=fsviewerlgpl$
- * Phoenix Firestorm Viewer Source Code
- * Copyright (C) 2012, Cinder Roxley <cinder.roxley@phoenixviewer.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
- * http://www.firestormviewer.org
- * $/LicenseInfo$
- */
-
-#ifndef FS_FLOATERSEARCH_H
-#define FS_FLOATERSEARCH_H
-
-#include "llfloater.h"
-#include "lliconctrl.h"
-#include "lltexteditor.h"
-#include "lltexturectrl.h"
-#include "llremoteparcelrequest.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llgroupmgr.h"
-#include "llavatarnamecache.h"
-#include "llmediactrl.h"
-#include "llradiogroup.h"
-#include "llsearchcombobox.h"
-#include "llscrolllistctrl.h"
-#include "lltabcontainer.h"
-#include "lleventnotifier.h"
-
-class FSSearchRemoteParcelInfoObserver;
-class LLAvatarPropertiesObserver;
-class LLGroupMgrObserver;
-class LLSearchEditor;
-class LLSearchComboBox;
-class FSFloaterSearch;
-class LLPanelProfile;
-class FSScrollListCtrl;
-
-struct SearchQuery : public LLInitParam::Block<SearchQuery>
-{
-    Optional<std::string> category;
-    Optional<std::string> query;
-
-    SearchQuery();
-};
-
-///////////////////////////////
-//       Search Panels       //
-///////////////////////////////
-
-class FSSearchPanelBase : public LLPanel
-{
-public:
-    FSSearchPanelBase() : LLPanel() { }
-    virtual ~FSSearchPanelBase() = default;
-    virtual void focusDefaultElement() { }
-};
-
-class FSPanelSearchPeople : public FSSearchPanelBase
-{
-    LOG_CLASS(FSFloaterSearch);
-public:
-    FSPanelSearchPeople();
-    static void processSearchReply(LLMessageSystem* msg, void**);
-
-    /*virtual*/ void focusDefaultElement();
-
-protected:
-    const S32& getNumResultsReturned() const { return mNumResultsReturned; };
-    const S32& getNumResultsReceived() const { return mResultsReceived; };
-
-private:
-    /*virtual*/ BOOL postBuild();
-    virtual ~FSPanelSearchPeople();
-
-    void onBtnFind();
-    void onSelectItem();
-    void onBtnNext();
-    void onBtnBack();
-
-    void find();
-    void resetSearch();
-    S32  showNextButton(S32);
-
-    const LLUUID& getQueryID() const { return mQueryID; }
-
-    void onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name);
-
-    typedef boost::signals2::connection avatar_name_callback_connection_t;
-    avatar_name_callback_connection_t mAvatarNameCallbackConnection;
-
-    S32         mNumResultsReturned;
-    S32         mStartSearch;
-    S32         mResultsReceived;
-    LLSD        mResultsContent;
-    LLUUID      mQueryID;
-
-    LLSearchComboBox*       mSearchComboBox;
-    LLScrollListCtrl*       mSearchResults;
-};
-
-class FSPanelSearchGroups : public FSSearchPanelBase
-{
-    LOG_CLASS(FSFloaterSearch);
-public:
-    FSPanelSearchGroups();
-    static void processSearchReply(LLMessageSystem* msg, void**);
-
-    /*virtual*/ void focusDefaultElement();
-
-private:
-    /*virtual*/ BOOL postBuild();
-    virtual ~FSPanelSearchGroups();
-
-    void onBtnFind();
-    void onSelectItem();
-    void onBtnNext();
-    void onBtnBack();
-
-    void find();
-    void resetSearch();
-    S32  showNextButton(S32);
-
-    const LLUUID& getQueryID() const { return mQueryID; }
-
-    S32         mNumResultsReturned;
-    S32         mStartSearch;
-    S32         mResultsReceived;
-    LLSD        mResultsContent;
-    LLUUID      mQueryID;
-
-    LLSearchComboBox*   mSearchComboBox;
-    LLScrollListCtrl*   mSearchResults;
-};
-
-class FSPanelSearchPlaces : public FSSearchPanelBase
-{
-    LOG_CLASS(FSFloaterSearch);
-public:
-    FSPanelSearchPlaces();
-    static void processSearchReply(LLMessageSystem* msg, void**);
-
-    /*virtual*/ void focusDefaultElement();
-
-private:
-    /*virtual*/ BOOL postBuild();
-    virtual ~FSPanelSearchPlaces();
-
-    void onBtnFind();
-    void onSelectItem();
-    void onBtnNext();
-    void onBtnBack();
-
-    void find();
-    void resetSearch();
-    S32  showNextButton(S32);
-
-    const LLUUID& getQueryID() const { return mQueryID; }
-
-    S32         mNumResultsReturned;
-    S32         mStartSearch;
-    S32         mResultsReceived;
-    LLSD        mResultsContent;
-    LLUUID      mQueryID;
-
-    LLSearchComboBox*   mSearchComboBox;
-    LLScrollListCtrl*   mSearchResults;
-    LLComboBox*         mPlacesCategory;
-};
-
-class FSPanelSearchLand : public FSSearchPanelBase
-{
-    LOG_CLASS(FSFloaterSearch);
-public:
-    FSPanelSearchLand();
-    static void processSearchReply(LLMessageSystem* msg, void**);
-
-private:
-    /*virtual*/ BOOL postBuild();
-    virtual ~FSPanelSearchLand();
-
-    void onBtnFind();
-    void onSelectItem();
-    void onBtnNext();
-    void onBtnBack();
-
-    void find();
-    void resetSearch();
-    S32  showNextButton(S32);
-
-    const LLUUID& getQueryID() const { return mQueryID; }
-
-    S32         mNumResultsReturned;
-    S32         mStartSearch;
-    S32         mResultsReceived;
-    LLSD        mResultsContent;
-    LLUUID      mQueryID;
-
-    LLLineEditor*       mPriceEditor;
-    LLLineEditor*       mAreaEditor;
-    LLScrollListCtrl*   mSearchResults;
-};
-
-class FSPanelSearchClassifieds : public FSSearchPanelBase
-{
-    LOG_CLASS(FSFloaterSearch);
-public:
-    FSPanelSearchClassifieds();
-    static void processSearchReply(LLMessageSystem* msg, void**);
-
-    /*virtual*/ void focusDefaultElement();
-
-private:
-    /*virtual*/ BOOL postBuild();
-    virtual ~FSPanelSearchClassifieds();
-
-    void onBtnFind();
-    void onSelectItem();
-    void onBtnNext();
-    void onBtnBack();
-
-    void find();
-    void resetSearch();
-    S32  showNextButton(S32);
-
-    const LLUUID& getQueryID() const { return mQueryID; }
-
-    S32         mNumResultsReturned;
-    S32         mStartSearch;
-    S32         mResultsReceived;
-    LLSD        mResultsContent;
-    LLUUID      mQueryID;
-
-    LLSearchComboBox*   mSearchComboBox;
-    LLScrollListCtrl*   mSearchResults;
-    LLComboBox*         mClassifiedsCategory;
-};
-
-class FSPanelSearchEvents : public FSSearchPanelBase
-{
-    LOG_CLASS(FSFloaterSearch);
-public:
-    FSPanelSearchEvents();
-    static void processSearchReply(LLMessageSystem* msg, void**);
-
-    /*virtual*/ void focusDefaultElement();
-
-private:
-    /*virtual*/ BOOL postBuild();
-    virtual ~FSPanelSearchEvents();
-
-    void onBtnFind();
-    void onSelectItem();
-    void onBtnNext();
-    void onBtnBack();
-    void onBtnTomorrow();
-    void onBtnYesterday();
-    void onBtnToday();
-
-    void find();
-    void setDay(S32 day);
-    void onSearchModeChanged();
-    void resetSearch();
-    S32  showNextButton(S32);
-
-    const LLUUID& getQueryID() const { return mQueryID; }
-
-    S32         mNumResultsReturned;
-    S32         mResultsReceived;
-    S32         mStartSearch;
-    S32         mDay;
-    LLSD        mResultsContent;
-    LLUUID      mQueryID;
-
-    LLSearchComboBox*   mSearchComboBox;
-    LLScrollListCtrl*   mSearchResults;
-    LLRadioGroup*       mEventsMode;
-};
-
-class FSPanelSearchWeb : public FSSearchPanelBase
-{
-    LOG_CLASS(FSFloaterSearch);
-public:
-    FSPanelSearchWeb();
-    /*virtual*/ BOOL postBuild();
-    void loadURL(const SearchQuery &query);
-    /*virtual*/ void focusDefaultElement();
-    /*virtual*/ void draw();
-    void resetFocusOnLoad() { mResetFocusOnLoad = true; }
-
-private:
-    virtual ~FSPanelSearchWeb() {};
-
-    LLMediaCtrl*    mWebBrowser;
-    LLSD            mCategoryPaths;
-
-    bool            mResetFocusOnLoad;
-};
-
-class FSFloaterSearch : public LLFloater
-{
-    LOG_CLASS(FSFloaterSearch);
-public:
-    typedef enum e_search_category
-    {
-        SC_AVATAR,
-        SC_GROUP,
-        SC_PLACE,
-        SC_CLASSIFIED
-    }   ESearchCategory;
-
-    struct _Params : public LLInitParam::Block<_Params, LLFloater::Params>
-    {
-        Optional<SearchQuery> search;
-    };
-
-    typedef LLSDParamAdapter<_Params> Params;
-
-    FSFloaterSearch(const Params& key);
-    ~FSFloaterSearch();
-    void onOpen(const LLSD& key);
-    BOOL postBuild();
-
-    void avatarNameUpdatedCallback(const LLUUID& id, const LLAvatarName& av_name);
-    void groupNameUpdatedCallback(const LLUUID& id, const std::string& name, bool is_group);
-    void onSelectedItem(const LLUUID& selected_item, ESearchCategory type);
-    void onSelectedEvent(const S32 selected_event);
-    void displayParcelDetails(const LLParcelData& parcel_data);
-    void displayClassifiedDetails(LLAvatarClassifiedInfo*& c_info);
-    void displayAvatarDetails(LLAvatarData* avatar_data);
-    void displayGroupDetails(LLGroupMgrGroupData*& group_data);
-    bool displayEventDetails(LLEventStruct event);
-    void displayEventParcelImage(const LLParcelData& parcel_data);
-    void setLoadingProgress(bool started);
-
-    template <class T>
-    static T* getSearchPanel(const std::string& panel_name);
-
-private:
-    virtual void onClose(bool app_quitting);
-    const LLUUID& getSelectedID() { return mSelectedID; }
-    LLVector3d  mParcelGlobal;
-    LLUUID      mSelectedID;
-    U32         mEventID;
-    bool        mHasSelection;
-
-    void resetVerbs();
-    void flushDetails();
-    void onTabChange();
-    void onBtnPeopleProfile();
-    void onBtnPeopleIM();
-    void onBtnPeopleFriend();
-    void onBtnGroupProfile();
-    void onBtnGroupChat();
-    void onBtnGroupJoin();
-    void onBtnEventReminder();
-    void onBtnTeleport();
-    void onBtnMap();
-
-    void regionHandleCallback(U64 region_handle, LLVector3d pos_global);
-
-    FSSearchRemoteParcelInfoObserver* mRemoteParcelObserver;
-    FSSearchRemoteParcelInfoObserver* mRemoteParcelEventLocationObserver;
-    LLAvatarPropertiesObserver* mAvatarPropertiesObserver;
-    LLGroupMgrObserver* mGroupPropertiesRequest;
-    boost::signals2::connection mEventNotifierConnection;
-
-    FSPanelSearchPeople*    mPanelPeople;
-    FSPanelSearchGroups*    mPanelGroups;
-    FSPanelSearchPlaces*    mPanelPlaces;
-    FSPanelSearchEvents*    mPanelEvents;
-    FSPanelSearchLand*      mPanelLand;
-    FSPanelSearchClassifieds* mPanelClassifieds;
-    FSPanelSearchWeb*       mPanelWeb;
-
-    LLPanel*        mDetailsPanel;
-    LLTextEditor*   mDetailTitle;
-    LLTextEditor*   mDetailDesc;
-    LLTextEditor*   mDetailAux1;
-    LLTextEditor*   mDetailAux2;
-    LLTextEditor*   mDetailLocation;
-    LLTextureCtrl*  mDetailSnapshot;
-    LLTextureCtrl*  mDetailSnapshotParcel;
-    LLIconCtrl*     mDetailMaturity;
-    LLTabContainer* mTabContainer;
-};
-
-#endif // FS_FLOATERSEARCH_H
diff --git a/indra/newview/llagenthandler.cpp b/indra/newview/llagenthandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..688aa2b6aee172bc3932488941ea929e79ea1464
--- /dev/null
+++ b/indra/newview/llagenthandler.cpp
@@ -0,0 +1,188 @@
+/**
+ * @file llagenthandler.cpp
+ * @brief Command handler involving agent requests
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llavataractions.h"
+#include "llcommandhandler.h"
+#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
+#include "llmutelist.h"
+#include "llnotificationsutil.h"
+//#include "llpanelblockedlist.h"
+#include "llfloaterblocked.h"
+
+class LLAgentHandler : public LLCommandHandler
+{
+public:
+    // requires trusted browser to trigger
+    LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { }
+
+    virtual bool canHandleUntrusted(
+        const LLSD& params,
+        const LLSD& query_map,
+        LLMediaCtrl* web,
+        const std::string& nav_type)
+    {
+        if (params.size() < 2)
+        {
+            return true; // don't block, will fail later
+        }
+
+        if (nav_type == NAV_TYPE_CLICKED
+            || nav_type == NAV_TYPE_EXTERNAL)
+        {
+            return true;
+        }
+
+        const std::string verb = params[1].asString();
+        if (verb == "about" || verb == "inspect" || verb == "reportAbuse")
+        {
+            return true;
+        }
+        return false;
+    }
+
+    bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid,
+        LLMediaCtrl* web)
+    {
+        if (params.size() < 2) return false;
+        LLUUID avatar_id;
+        if (!avatar_id.set(params[0].asStringRef(), FALSE))
+        {
+            return false;
+        }
+
+        const std::string verb = params[1].asString();
+        if (verb == "about")
+        {
+            LLAvatarActions::showProfile(avatar_id);
+            return true;
+        }
+
+        if (verb == "inspect")
+        {
+            LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", avatar_id));
+            return true;
+        }
+
+        if (verb == "im")
+        {
+            LLAvatarActions::startIM(avatar_id);
+            return true;
+        }
+
+        if (verb == "pay")
+        {
+            if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableAvatarPay"))
+            {
+                LLNotificationsUtil::add("NoAvatarPay", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+                return true;
+            }
+
+            LLAvatarActions::pay(avatar_id);
+            return true;
+        }
+
+        if (verb == "offerteleport")
+        {
+            LLAvatarActions::offerTeleport(avatar_id);
+            return true;
+        }
+
+        if (verb == "requestfriend")
+        {
+            LLAvatarActions::requestFriendshipDialog(avatar_id);
+            return true;
+        }
+
+        if (verb == "removefriend")
+        {
+            LLAvatarActions::removeFriendDialog(avatar_id);
+            return true;
+        }
+
+        if (verb == "mute")
+        {
+            if (! LLAvatarActions::isBlocked(avatar_id))
+            {
+                LLAvatarActions::toggleBlock(avatar_id);
+            }
+            return true;
+        }
+
+        if (verb == "unmute")
+        {
+            if (LLAvatarActions::isBlocked(avatar_id))
+            {
+                LLAvatarActions::toggleBlock(avatar_id);
+            }
+            return true;
+        }
+
+        if (verb == "block")
+        {
+            if (params.size() > 2)
+            {
+                const std::string object_name = LLURI::unescape(params[2].asString());
+                LLMute mute(avatar_id, object_name, LLMute::OBJECT);
+                LLMuteList::getInstance()->add(mute);
+                LLFloaterBlocked::showMuteAndSelect(mute.mID);
+                //LLPanelBlockedList::showPanelAndSelect(mute.mID);
+            }
+            return true;
+        }
+
+        if (verb == "unblock")
+        {
+            if (params.size() > 2)
+            {
+                const std::string object_name = params[2].asString();
+                LLMute mute(avatar_id, object_name, LLMute::OBJECT);
+                LLMuteList::getInstance()->remove(mute);
+            }
+            return true;
+        }
+
+        // reportAbuse is here due to convoluted avatar handling
+        // in LLScrollListCtrl and LLTextBase
+        if (verb == "reportAbuse" && web == NULL)
+        {
+            LLAvatarName av_name;
+            if (LLAvatarNameCache::get(avatar_id, &av_name))
+            {
+                LLFloaterReporter::showFromAvatar(avatar_id, av_name.getCompleteName());
+            }
+            else
+            {
+                LLFloaterReporter::showFromAvatar(avatar_id, "not avaliable");
+            }
+            return true;
+        }
+        return false;
+    }
+};
+LLAgentHandler gAgentHandler;
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 927618a0865d248a603c44b0a6a056c86b65c796..51e5dcd8d96aa1862511ce914b404752e0d6f27f 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -50,6 +50,7 @@
 #include "llfloaterreg.h"
 #include "llfloaterpay.h"
 #include "llfloaterprofile.h"
+#include "llfloaterprofilelegacy.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfloaterwebcontent.h"
 #include "llfloaterworldmap.h"
@@ -64,6 +65,7 @@
 #include "llnotificationsutil.h"    // for LLNotificationsUtil
 #include "llpaneloutfitedit.h"
 #include "llpanelprofile.h"
+#include "llpanelprofilelegacy.h"
 #include "llparcel.h"
 #include "llrecentpeople.h"
 #include "lltrans.h"
@@ -378,7 +380,15 @@ void LLAvatarActions::showProfile(const LLUUID& avatar_id)
 {
     if (avatar_id.notNull())
     {
-        LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id));
+        if (gSkinSettings.getBool("LegacyProfile"))
+        {
+            LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>(
+                "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES);
+        }
+        else
+        {
+            LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id));
+        }
     }
 }
 
@@ -387,10 +397,21 @@ void LLAvatarActions::showPicks(const LLUUID& avatar_id)
 {
     if (avatar_id.notNull())
     {
-        LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
-        if (profilefloater)
+        if (gSkinSettings.getBool("LegacyProfile"))
+        {
+            const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>(
+                "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES);
+            LLPanel* tab = profile->expandTab("avatar_picks_tab");
+            tab->getChild<LLAccordionCtrl>("accordion")->expandTab("tab_picks");
+        }
+        else
         {
-            profilefloater->showPick();
+            LLFloaterProfile* profile = LLFloaterReg::showTypedInstance<LLFloaterProfile>(
+                "profile", LLSD().with("id", avatar_id));
+            if (profile)
+            {
+                profile->showPick();
+            }
         }
     }
 }
@@ -400,10 +421,20 @@ void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id)
 {
     if (avatar_id.notNull())
     {
-        LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
-        if (profilefloater)
+        if (gSkinSettings.getBool("LegacyProfile"))
+        {
+            const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>(
+                "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES);
+            /*auto* tab = */dynamic_cast<LLPanelProfileLegacy::LLPanelProfilePicks*>(profile->expandTab("avatar_picks_tab"));
+            // *TODO: Finish
+        }
+        else
         {
-            profilefloater->showPick(pick_id);
+            LLFloaterProfile* profile = LLFloaterReg::showTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+            if (profile)
+            {
+                profile->showPick(pick_id);
+            }
         }
     }
 }
@@ -411,9 +442,9 @@ void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id)
 // static
 void LLAvatarActions::createPick()
 {
-    LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+
     LLViewerRegion* region = gAgent.getRegion();
-    if (profilefloater && region)
+    if (region)
     {
         LLPickData data;
         data.pos_global = gAgent.getPositionGlobal();
@@ -431,8 +462,7 @@ void LLAvatarActions::createPick()
         {
             data.name = region->getName();
         }
-
-        profilefloater->createPick(data);
+        createPick(data);
     }
 }
 
@@ -441,10 +471,21 @@ bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id)
 {
     if (avatar_id.notNull())
     {
-        LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
-        if (profilefloater)
+        static LLCachedControl<bool> legacy_profile(gSkinSettings, "LegacyProfile");
+        if (legacy_profile)
+        {
+            const LLFloaterProfileLegacy* profile = LLFloaterReg::findTypedInstance<LLFloaterProfileLegacy>(
+                "legacy_profile", LLSD().with("avatar_id", avatar_id));
+            if (profile == nullptr) { return false; }
+            return dynamic_cast<LLPanelProfileLegacy::LLPanelProfilePicks*>(profile->getExpandedTab()) != nullptr;
+        }
+        else
         {
-            return profilefloater->isPickTabSelected();
+            LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+            if (profilefloater)
+            {
+                return profilefloater->isPickTabSelected();
+            }
         }
     }
     return false;
@@ -455,10 +496,21 @@ void LLAvatarActions::showClassifieds(const LLUUID& avatar_id)
 {
     if (avatar_id.notNull())
     {
-        LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
-        if (profilefloater)
+        if (gSkinSettings.getBool("LegacyProfile"))
         {
-            profilefloater->showClassified();
+            const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>(
+                "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES);
+            LLPanel* tab = profile->expandTab("avatar_picks_tab");
+            tab->getChild<LLAccordionCtrl>("accordion")->expandTab("tab_classifieds");
+        }
+        else
+        {
+            LLFloaterProfile* profilefloater = LLFloaterReg::showTypedInstance<LLFloaterProfile>(
+                "profile", LLSD().with("id", avatar_id));
+            if (profilefloater)
+            {
+                profilefloater->showClassified();
+            }
         }
     }
 }
@@ -468,10 +520,22 @@ void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& clas
 {
     if (avatar_id.notNull())
     {
-        LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
-        if (profilefloater)
+        if (gSkinSettings.getBool("LegacyProfile"))
+        {
+            const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>(
+                "legacy_profile", LLSD().with("avatar_id", avatar_id), TAKE_FOCUS_YES);
+            LLPanel* tab = profile->expandTab("avatar_picks_tab");
+            tab->getChild<LLAccordionCtrl>("accordion")->expandTab("tab_classifieds");
+            // *TODO: Finish
+        }
+        else
         {
-            profilefloater->showClassified(classified_id, edit);
+            LLFloaterProfile* profilefloater =
+                dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+            if (profilefloater)
+            {
+                profilefloater->showClassified(classified_id, edit);
+            }
         }
     }
 }
@@ -479,35 +543,68 @@ void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& clas
 // static
 void LLAvatarActions::createClassified()
 {
-    LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
-    if (profilefloater)
+    if (gSkinSettings.getBool("LegacyProfile"))
     {
-        profilefloater->createClassified();
+        const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>(
+            "legacy_profile", LLSD().with("avatar_id", gAgent.getID()));
+        auto* tab = dynamic_cast<LLPanelProfileLegacy::LLPanelProfilePicks*>(profile->expandTab("avatar_picks_tab"));
+        tab->createNewClassified();
+
+    }
+    else
+    {
+        LLFloaterProfile* profilefloater =
+            dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+        if (profilefloater)
+        {
+            profilefloater->createClassified();
+        }
     }
 }
 
 //static
 bool LLAvatarActions::profileVisible(const LLUUID& avatar_id)
 {
-    LLSD sd;
-    sd["id"] = avatar_id;
-    LLFloater* floater = getProfileFloater(avatar_id);
+    LLFloater* floater = findProfileFloater(avatar_id);
     return floater && floater->isShown();
 }
 
 //static
-LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id)
+LLFloater* LLAvatarActions::findProfileFloater(const LLUUID& avatar_id)
 {
-    LLFloaterProfile* floater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
-    return floater;
+    LLFloater* profile = nullptr;
+    static LLCachedControl<bool> legacy_profile(gSkinSettings, "LegacyProfile");
+    if (legacy_profile)
+        profile = LLFloaterReg::findTypedInstance<LLFloaterProfileLegacy>("legacy_profile", LLSD().with("avatar_id", avatar_id));
+    else
+        profile = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+    return profile;
+}
+
+void LLAvatarActions::createPick(const LLPickData& data)
+{
+    if (gSkinSettings.getBool("LegacyProfile"))
+    {
+        const LLFloaterProfileLegacy* profile = LLFloaterReg::showTypedInstance<LLFloaterProfileLegacy>(
+            "legacy_profile", LLSD().with("avatar_id", gAgent.getID()));
+        auto* tab = dynamic_cast<LLPanelProfileLegacy::LLPanelProfilePicks*>(profile->expandTab("avatar_picks_tab"));
+        tab->createNewPick();
+    }
+    else
+    {
+        LLFloaterProfile* floater =
+            dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+        if (floater)
+        {
+            floater->createPick(data);
+        }
+    }
 }
 
 //static
 void LLAvatarActions::hideProfile(const LLUUID& avatar_id)
 {
-    LLSD sd;
-    sd["id"] = avatar_id;
-    LLFloater* floater = getProfileFloater(avatar_id);
+    LLFloater* floater = findProfileFloater(avatar_id);
     if (floater)
     {
         floater->closeFloater();
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 2493ec2b5030f90658b0ca32c57c7d3a681454bd..f69954bfe43b595fedcf8799dde076854ed15bf6 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -107,7 +107,9 @@ class LLAvatarActions
     static void hideProfile(const LLUUID& avatar_id);
     static bool profileVisible(const LLUUID& avatar_id);
     static bool isPickTabSelected(const LLUUID& avatar_id);
-    static LLFloater* getProfileFloater(const LLUUID& avatar_id);
+    static LLFloater* findProfileFloater(const LLUUID& avatar_id);
+
+    static void createPick(const LLPickData& data);
 
     /**
      * Show avatar on world map.
diff --git a/indra/newview/llclassifieditem.cpp b/indra/newview/llclassifieditem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0f0f6924e0bec78c0befbca2f2b7d728aa03fb41
--- /dev/null
+++ b/indra/newview/llclassifieditem.cpp
@@ -0,0 +1,119 @@
+/**
+* @file llclassifieditem.cpp
+* @brief Widget
+*
+* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llclassifieditem.h"
+
+#include "llpanelclassified.h"
+
+LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id)
+    : LLPanel()
+    , mAvatarId(avatar_id)
+    , mClassifiedId(classified_id)
+{
+    buildFromFile("panel_classifieds_list_item.xml");
+
+    LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
+    LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+}
+
+LLClassifiedItem::~LLClassifiedItem()
+{
+    LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+}
+
+void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type)
+{
+    if (APT_CLASSIFIED_INFO != type)
+    {
+        return;
+    }
+
+    LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+    if (!c_info || c_info->classified_id != getClassifiedId())
+    {
+        return;
+    }
+
+    setClassifiedName(c_info->name);
+    setDescription(c_info->description);
+    setSnapshotId(c_info->snapshot_id);
+    setPosGlobal(c_info->pos_global);
+
+    LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+}
+
+BOOL LLClassifiedItem::postBuild()
+{
+    setMouseEnterCallback(std::bind(&set_child_visible, this, "hovered_icon", true));
+    setMouseLeaveCallback(std::bind(&set_child_visible, this, "hovered_icon", false));
+    return TRUE;
+}
+
+void LLClassifiedItem::setValue(const LLSD& value)
+{
+    if (!value.isMap()) return;;
+    if (!value.has("selected")) return;
+    getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
+void LLClassifiedItem::fillIn(LLPanelClassifiedEdit* panel)
+{
+    if (!panel)
+    {
+        return;
+    }
+
+    setClassifiedName(panel->getClassifiedName());
+    setDescription(panel->getDescription());
+    setSnapshotId(panel->getSnapshotId());
+    setCategory(panel->getCategory());
+    setContentType(panel->getContentType());
+    setAutoRenew(panel->getAutoRenew());
+    setPriceForListing(panel->getPriceForListing());
+    setPosGlobal(panel->getPosGlobal());
+    setLocationText(panel->getClassifiedLocation());
+}
+
+void LLClassifiedItem::setClassifiedName(const std::string& name)
+{
+    getChild<LLUICtrl>("name")->setValue(name);
+}
+
+void LLClassifiedItem::setDescription(const std::string& desc)
+{
+    getChild<LLUICtrl>("description")->setValue(desc);
+}
+
+void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id)
+{
+    getChild<LLUICtrl>("picture")->setValue(snapshot_id);
+}
+
+LLUUID LLClassifiedItem::getSnapshotId() const
+{
+    return getChild<LLUICtrl>("picture")->getValue();
+}
diff --git a/indra/newview/llclassifieditem.h b/indra/newview/llclassifieditem.h
new file mode 100644
index 0000000000000000000000000000000000000000..212a53ee0c693055e52ad60aecce0c99f95d5bc3
--- /dev/null
+++ b/indra/newview/llclassifieditem.h
@@ -0,0 +1,83 @@
+/**
+* @file llclassifieditem.h
+* @brief Widget
+*
+* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_CLASSIFIEDITEM_H
+#define LL_CLASSIFIEDITEM_H
+
+#include "llavatarpropertiesprocessor.h"
+#include "llpanel.h"
+
+class LLPanelClassifiedEdit;
+
+static const std::string CLASSIFIED_ID("classified_id");
+static const std::string CLASSIFIED_NAME("classified_name");
+
+class LLClassifiedItem final : public LLPanel, public LLAvatarPropertiesObserver
+{
+public:
+
+    LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id);
+    virtual ~LLClassifiedItem();
+
+    void processProperties(void* data, EAvatarProcessorType type) override;
+    BOOL postBuild() override;
+    void setValue(const LLSD& value) override;
+    void fillIn(LLPanelClassifiedEdit* panel);
+    LLUUID getAvatarId() const { return mAvatarId; }
+    void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
+    LLUUID getClassifiedId() const { return mClassifiedId; }
+    void setClassifiedId(const LLUUID& classified_id) { mClassifiedId = classified_id; }
+    void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+    const LLVector3d getPosGlobal() const { return mPosGlobal; }
+    void setLocationText(const std::string location) { mLocationText = std::move(location); }
+    std::string getLocationText() const { return mLocationText; }
+    void setClassifiedName(const std::string& name);
+    std::string getClassifiedName() const { return getChild<LLUICtrl>("name")->getValue().asString(); }
+    void setDescription(const std::string& desc);
+    std::string getDescription() const { return getChild<LLUICtrl>("description")->getValue().asString(); }
+    void setSnapshotId(const LLUUID& snapshot_id);
+    LLUUID getSnapshotId() const;
+    void setCategory(U32 cat) { mCategory = cat; }
+    U32 getCategory() const { return mCategory; }
+    void setContentType(U32 ct) { mContentType = ct; }
+    U32 getContentType() const { return mContentType; }
+    void setAutoRenew(U32 renew) { mAutoRenew = renew; }
+    bool getAutoRenew() const { return mAutoRenew; }
+    void setPriceForListing(S32 price) { mPriceForListing = price; }
+    S32 getPriceForListing() const { return mPriceForListing; }
+
+private:
+    LLUUID mAvatarId;
+    LLUUID mClassifiedId;
+    LLVector3d mPosGlobal;
+    std::string mLocationText;
+    U32 mCategory;
+    U32 mContentType;
+    bool mAutoRenew;
+    S32 mPriceForListing;
+};
+
+#endif // LL_CLASSIFIEDITEM_H
diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp
index 04aad5aa0f41176cabe0a61dd6e98c4157a636ad..4bc481b21ec2415fee09a4e9cbfd283b70b81759 100644
--- a/indra/newview/lleventnotifier.cpp
+++ b/indra/newview/lleventnotifier.cpp
@@ -168,7 +168,8 @@ bool LLEventNotifier::handleResponse(U32 eventId, const LLSD& notification, cons
 
 bool LLEventNotifier::add(const LLEventStruct& event)
 {
-    if (mNewEventSignal(event)) return false;
+    if (mNewEventSignal(event)) { return false; }
+
     LLEventNotification *new_enp = new LLEventNotification(event.eventId, event.eventEpoch, event.eventDateStr, event.eventName);
 
     LL_INFOS() << "Add event " << event.eventName << " id " << event.eventId << " date " << event.eventDateStr << LL_ENDL;
@@ -207,21 +208,21 @@ void LLEventNotifier::processEventInfoReply(LLMessageSystem *msg, void **)
     U32 event_time_utc;
 
     msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
-    msg->getU32("EventData", "EventID", event_id);
-    msg->getString("EventData", "Name", event_name);
-    msg->getString("EventData", "Date", eventd_date);
-    msg->getU32("EventData", "DateUTC", event_time_utc);
+    msg->getU32Fast(_PREHASH_EventData, _PREHASH_EventID, event_id);
+    msg->getStringFast(_PREHASH_EventData, _PREHASH_Name, event_name);
+    msg->getStringFast(_PREHASH_EventData, _PREHASH_Date, eventd_date);
+    msg->getU32Fast(_PREHASH_EventData, _PREHASH_DateUTC, event_time_utc);
 
     LLEventStruct event(event_id, (F64)event_time_utc, eventd_date, event_name);
-    msg->getString("EventData", "Creator", event.creator);
-    msg->getString("EventData", "Category", event.category);
-    msg->getString("EventData", "Desc", event.desc);
-    msg->getU32("EventData", "Duration", event.duration);
-    msg->getU32("EventData", "Cover", event.cover);
-    msg->getU32("EventData", "Amount", event.amount);
-    msg->getString("EventData", "SimName", event.simName);
-    msg->getVector3d("EventData", "GlobalPos", event.globalPos);
-    msg->getU32("EventData", "EventFlags", event.flags);
+    msg->getString(_PREHASH_EventData, _PREHASH_Creator, event.creator);
+    msg->getString(_PREHASH_EventData, _PREHASH_Category, event.category);
+    msg->getString(_PREHASH_EventData, _PREHASH_Desc, event.desc);
+    msg->getU32(_PREHASH_EventData, _PREHASH_Duration, event.duration);
+    msg->getU32(_PREHASH_EventData, _PREHASH_Cover, event.cover);
+    msg->getU32(_PREHASH_EventData, _PREHASH_Amount, event.amount);
+    msg->getString(_PREHASH_EventData, _PREHASH_SimName, event.simName);
+    msg->getVector3d(_PREHASH_EventData, _PREHASH_GlobalPos, event.globalPos);
+    msg->getU32(_PREHASH_EventData, _PREHASH_EventFlags, event.flags);
 
     gEventNotifier.add(event);
 }
@@ -246,29 +247,22 @@ void LLEventNotifier::load(const LLSD& event_options)
             is_iso8601_date = true;
         }
 
+        std::string dateStr = response["event_date"].asString();
+
         if (is_iso8601_date)
         {
-            std::string dateStr;
-
-            dateStr = "[" + LLTrans::getString("LTimeYear") + "]-["
-                + LLTrans::getString("LTimeMthNum") + "]-["
-                + LLTrans::getString("LTimeDay") + "] ["
-                + LLTrans::getString("LTimeHour") + "]:["
-                + LLTrans::getString("LTimeMin") + "]:["
-                + LLTrans::getString("LTimeSec") + "]";
+            std::string iso8601date =
+                "[" + LLTrans::getString("LTimeYear") + "]-[" + LLTrans::getString("LTimeMthNum") + "]-["
+                    + LLTrans::getString("LTimeDay") + "] [" + LLTrans::getString("LTimeHour") + "]:["
+                    + LLTrans::getString("LTimeMin") + "]:[" + LLTrans::getString("LTimeSec") + "]";
 
             LLSD substitution;
             substitution["datetime"] = date;
-            LLStringUtil::format(dateStr, substitution);
-
-            LLEventStruct event(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString());
-            add(event);
-        }
-        else
-        {
-            LLEventStruct event(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString());
-            add(event);
+            LLStringUtil::format(iso8601date, substitution);
+            dateStr = iso8601date;
         }
+
+        add(LLEventStruct(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString()));
     }
 }
 
@@ -311,11 +305,11 @@ void LLEventNotifier::serverPushRequest(U32 event_id, bool add)
 }
 
 
-LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, std::string eventDateStr, std::string eventName) :
+LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName) :
     mEventID(eventId),
-    mEventName(std::move(eventName)),
+    mEventName(eventName),
     mEventDateEpoch(eventEpoch),
-    mEventDateStr(std::move(eventDateStr))
+    mEventDateStr(eventDateStr)
 {
 
 }
diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h
index f30039f51b0fc5fcd16ade19d0980d99b58be5c9..14ced4908d8fe417ac18d6cf1f760fe2dedc6e6d 100644
--- a/indra/newview/lleventnotifier.h
+++ b/indra/newview/lleventnotifier.h
@@ -27,7 +27,6 @@
 #ifndef LL_LLEVENTNOTIFIER_H
 #define LL_LLEVENTNOTIFIER_H
 
-#include <utility>
 #include "llframetimer.h"
 #include "v3dmath.h"
 
@@ -48,9 +47,9 @@ typedef struct event_st{
     std::string simName;
     LLVector3d globalPos;
     U32 flags = 0;
-    event_st(U32 id, F64 epoch, std::string date_str, std::string name)
-        : eventId(id), eventEpoch(epoch), eventDateStr(std::move(date_str)), eventName(std::move(name)){}
-    event_st() = default;
+    event_st(U32 id, F64 epoch, const std::string& date_str, const std::string& name)
+        : eventId(id), eventEpoch(epoch), eventDateStr(date_str), eventName(name){}
+    event_st(){}
 } LLEventStruct;
 
 class LLEventNotifier
@@ -91,12 +90,12 @@ class LLEventNotifier
 class LLEventNotification
 {
 public:
-    LLEventNotification(U32 eventId, F64 eventEpoch, std::string eventDateStr, std::string eventName);
+    LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName);
 
 
     U32                 getEventID() const              { return mEventID; }
     const std::string   &getEventName() const           { return mEventName; }
-    bool                isValid() const                 { return mEventID > 0 && mEventDateEpoch != 0 && !mEventName.empty(); }
+    bool                isValid() const                 { return mEventID > 0 && mEventDateEpoch != 0 && mEventName.size() > 0; }
     const F64           &getEventDateEpoch() const      { return mEventDateEpoch; }
     const std::string   &getEventDateStr() const        { return mEventDateStr; }
 
diff --git a/indra/newview/llfloaterdirectory.cpp b/indra/newview/llfloaterdirectory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1df46a66fdbeb6d7ce81e9a480eaccf6f2aff56c
--- /dev/null
+++ b/indra/newview/llfloaterdirectory.cpp
@@ -0,0 +1,1219 @@
+/*
+ * @file llfloaterdirectory.cpp
+ * @brief Legacy search facility
+ *
+ * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterdirectory.h"
+
+// llmessage
+#include "lleventflags.h"
+#include "llqueryflags.h"
+#include "message.h"
+
+// llui
+#include "llfloaterreg.h"
+#include "lllayoutstack.h"
+#include "llpanel.h"
+#include "llresmgr.h"
+#include "llscrolllistctrl.h"
+#include "lltabcontainer.h"
+#include "lltextbase.h"
+#include "lltrans.h"
+
+// newview
+#include "llagent.h"
+#include "llpanelsearchbase.h"
+#include "llpanelsearchweb.h"
+#include "llproductinforequest.h"
+#include "llviewercontrol.h"
+
+SearchQuery::SearchQuery()
+:   category("category", ""),
+    collection("collection", ""),
+    query("query")
+{}
+
+static const std::array<std::string, 6> sSearchPanels{ {"panel_search_people", "panel_search_groups", "panel_search_places", "panel_search_classifieds", "panel_search_events", "panel_search_landsales"} };
+static const std::array<std::string, 5> sDetailPanels{ {"detail_avatar", "detail_group", "detail_place", "detail_classified", "detail_event"} };
+
+LLFloaterDirectory::LLFloaterDirectory(const Params& key)
+    : LLFloater(key)
+    , mCurrentResultType(SE_UNDEFINED)
+    , mCurrentQuery()
+    , mResultStart(0)
+    , mNumResultsReceived(0)
+    , mQueryID()
+    , mTabContainer(nullptr)
+    , mPanelWeb(nullptr)
+    , mResultList(nullptr)
+    , mResultsStatus(nullptr)
+{
+}
+
+LLFloaterDirectory::~LLFloaterDirectory()
+{
+}
+
+BOOL LLFloaterDirectory::postBuild()
+{
+    mResultList = findChild<LLScrollListCtrl>("results");
+    mResultList->setCommitCallback(boost::bind(&LLFloaterDirectory::onCommitSelection, this));
+    for (std::string panel_name: sSearchPanels)
+    {
+        LLPanelSearch* panel = static_cast<LLPanelSearch*>(findChild<LLUICtrl>(panel_name));
+        if (panel)
+            panel->setSearchFloater(this);
+    }
+    mPanelWeb = findChild<LLPanelSearchWeb>("panel_search_web");
+    mTabContainer = findChild<LLTabContainer>("search_tabs");
+    mTabContainer->setCommitCallback(boost::bind(&LLFloaterDirectory::onTabChanged, this));
+    setProgress(false);
+    mResultsStatus = findChild<LLTextBase>("results_status");
+    getChild<LLButton>("PageUp")->setCommitCallback(boost::bind(&LLFloaterDirectory::choosePage, this, _1));
+    getChild<LLButton>("PageDn")->setCommitCallback(boost::bind(&LLFloaterDirectory::choosePage, this, _1));
+    showDetailPanel(LLStringUtil::null); // hide all the panels
+    paginate();
+
+    if (!mTabContainer->selectTab(gSavedSettings.getS32("AlchemyLastDirectoryTab")))
+    {
+        mTabContainer->selectFirstTab();
+    }
+
+    return LLFloater::postBuild();
+}
+
+void LLFloaterDirectory::onOpen(const LLSD& key)
+{
+    Params p(key);
+    mPanelWeb->loadUrl(p.search);
+    if (key.has("query"))
+    {
+        mTabContainer->selectTabPanel(mPanelWeb);
+    }
+    onTabChanged();
+}
+
+void LLFloaterDirectory::onClose(bool app_quitting)
+{
+    if (mTabContainer)
+    {
+        gSavedSettings.setS32("AlchemyLastDirectoryTab", mTabContainer->getCurrentPanelIndex());
+    }
+}
+
+void LLFloaterDirectory::setProgress(bool working)
+{
+    getChild<LLUICtrl>("loading")->setVisible(working);
+}
+
+void LLFloaterDirectory::setResultsComment(const std::string& message)
+{
+    mResultList->setCommentText(message);
+}
+
+void LLFloaterDirectory::onTabChanged()
+{
+    LLPanel* active_panel = mTabContainer->getCurrentPanel();
+    bool show_detail = active_panel != mPanelWeb;
+    findChild<LLLayoutStack>("results_stack")->setVisible(show_detail);
+    findChild<LLButton>("PageUp")->setVisible(show_detail);
+    findChild<LLButton>("PageDn")->setVisible(show_detail);
+    mResultsStatus->setVisible(show_detail);
+}
+
+void LLFloaterDirectory::onCommitSelection()
+{
+    switch (mCurrentResultType)
+    {
+        case SE_PEOPLE:
+        {
+            LLSD params;
+            params["avatar_id"] = mResultList->getSelectedValue().asUUID();
+            getChild<LLPanel>("detail_avatar")->onOpen(params);
+            showDetailPanel("detail_avatar");
+            break;
+        }
+        case SE_GROUPS:
+        {
+            LLSD params;
+            params["group_id"] = mResultList->getSelectedValue().asUUID();
+            getChild<LLPanel>("detail_group")->onOpen(params);
+            showDetailPanel("detail_group");
+            break;
+        }
+        case SE_LANDSALES:
+        case SE_PLACES:
+        {
+            LLSD params;
+            params["type"] = "remote_place";
+            params["id"] = mResultList->getSelectedValue().asUUID();
+            getChild<LLPanel>("detail_place")->onOpen(params);
+            showDetailPanel("detail_place");
+            break;
+        }
+        case SE_CLASSIFIEDS:
+        {
+            LLSD params;
+            params["classified_id"] = mResultList->getSelectedValue().asUUID();
+            getChild<LLPanel>("detail_classified")->onOpen(params);
+            showDetailPanel("detail_classified");
+            break;
+        }
+        case SE_EVENTS:
+        {
+            getChild<LLPanel>("detail_event")->onOpen(mResultList->getSelectedValue().asInteger());
+            showDetailPanel("detail_event");
+            break;
+        }
+        case SE_UNDEFINED:
+        default:
+            LL_WARNS("Search") << "Unhandled search mode: " << mCurrentResultType << LL_ENDL;
+            break;
+    }
+}
+
+void LLFloaterDirectory::paginate()
+{
+    if (mNumResultsReceived)
+    {
+        LLStringUtil::format_map_t args;
+        std::string total_str;
+        LLResMgr::getInstance()->getIntegerString(total_str, mResultStart + mNumResultsReceived - 1);
+        args["TOTAL"] = total_str;
+        args["VISIBLE_END"] = total_str;
+        total_str = LLStringUtil::null;
+        LLResMgr::getInstance()->getIntegerString(total_str, mResultStart + 1);
+        args["VISIBLE_BEGIN"] = total_str;
+        mResultsStatus->setText(getString((mNumResultsReceived > mCurrentQuery.results_per_page)
+                                          ? "result_spillover" : "result_count",
+                                          args));
+    }
+    else
+        mResultsStatus->setText(getString("no_results"));
+    childSetEnabled("PageUp", mNumResultsReceived > mCurrentQuery.results_per_page);
+    childSetEnabled("PageDn", mResultStart > 0);
+}
+
+void LLFloaterDirectory::choosePage(LLUICtrl* ctrl)
+{
+    if (ctrl->getName() == "PageUp")
+        mResultStart += mCurrentQuery.results_per_page;
+    else if (ctrl->getName() == "PageDn")
+        mResultStart -= mCurrentQuery.results_per_page;
+    else
+    {
+        LL_WARNS("Search") << "Unknown control: " << ctrl->getName() << LL_ENDL;
+        return; // Fuck you, you lose.
+    }
+    queryDirectory(mCurrentQuery, false);
+}
+
+void LLFloaterDirectory::showDetailPanel(const std::string& panel_name)
+{
+    for (const std::string& panel_itr: sDetailPanels)
+    {
+        getChild<LLPanel>(panel_itr)->setVisible(panel_itr == panel_name);
+    }
+}
+
+void LLFloaterDirectory::rebuildResultList()
+{
+    mResultList->clearColumns();
+    switch (mCurrentResultType)
+    {
+        case SE_PEOPLE:
+        {
+            LLScrollListColumn::Params icon;
+            icon.name = "icon";
+            icon.width.pixel_width = 20;
+            mResultList->addColumn(icon);
+
+            LLScrollListColumn::Params name;
+            name.name = "name";
+            name.header.label = "Name";
+            name.width.relative_width = 1.f;
+            mResultList->addColumn(name);
+            break;
+        }
+        case SE_GROUPS:
+        {
+            LLScrollListColumn::Params icon;
+            icon.name = "icon";
+            icon.width.pixel_width = 20;
+            mResultList->addColumn(icon);
+
+            LLScrollListColumn::Params name;
+            name.name = "name";
+            name.header.label = "Name";
+            name.width.relative_width = 0.72f;
+            mResultList->addColumn(name);
+
+            LLScrollListColumn::Params members;
+            members.name = "members";
+            members.header.label = "Members";
+            members.width.relative_width = 0.25f;
+            mResultList->addColumn(members);
+
+            LLScrollListColumn::Params score;
+            score.name = "score";
+            score.header.label = "Score";
+            score.width.relative_width = 0.03f;
+            mResultList->addColumn(score);
+            break;
+        }
+        case SE_PLACES:
+        {
+            LLScrollListColumn::Params icon;
+            icon.name = "icon";
+            icon.width.pixel_width = 20;
+            mResultList->addColumn(icon);
+
+            LLScrollListColumn::Params name;
+            name.name = "name";
+            name.header.label = "Name";
+            name.width.relative_width = 0.81f;
+            mResultList->addColumn(name);
+
+            LLScrollListColumn::Params dwell;
+            dwell.name = "dwell";
+            dwell.header.label = "Traffic";
+            dwell.width.relative_width = 0.19f;
+            mResultList->addColumn(dwell);
+            break;
+        }
+        case SE_LANDSALES:
+        {
+            LLScrollListColumn::Params icon;
+            icon.name = "icon";
+            icon.width.pixel_width = 20;
+            mResultList->addColumn(icon);
+
+            LLScrollListColumn::Params name;
+            name.name = "name";
+            name.header.label = "Name";
+            name.width.relative_width = 0.45f;
+            mResultList->addColumn(name);
+
+            LLScrollListColumn::Params price;
+            price.name="price";
+            price.header.label="Price";
+            price.width.relative_width = 0.1f;
+            mResultList->addColumn(price);
+
+            LLScrollListColumn::Params area;
+            area.name="area";
+            area.header.label="Area";
+            area.width.relative_width = 0.1f;
+            mResultList->addColumn(area);
+
+            LLScrollListColumn::Params ppm;
+            ppm.name="ppm";
+            ppm.header.label="L$/m";
+            ppm.width.relative_width = 0.1f;
+            mResultList->addColumn(ppm);
+
+            LLScrollListColumn::Params type;
+            type.name="type";
+            type.header.label="Type";
+            type.width.relative_width = 0.2f;
+            mResultList->addColumn(type);
+            break;
+        }
+        case SE_CLASSIFIEDS:
+        {
+            LLScrollListColumn::Params icon;
+            icon.name = "icon";
+            icon.width.pixel_width = 20;
+            mResultList->addColumn(icon);
+
+            LLScrollListColumn::Params name;
+            name.name = "name";
+            name.header.label = "Name";
+            name.width.relative_width = 0.7f;
+            mResultList->addColumn(name);
+
+            LLScrollListColumn::Params price;
+            price.name="price";
+            price.header.label="Price";
+            price.width.relative_width = 0.3f;
+            mResultList->addColumn(price);
+            break;
+        }
+        case SE_EVENTS:
+        {
+            LLScrollListColumn::Params icon;
+            icon.name = "icon";
+            icon.width.pixel_width = 20;
+            mResultList->addColumn(icon);
+
+            LLScrollListColumn::Params name;
+            name.name = "name";
+            name.header.label = "Name";
+            name.width.relative_width = 0.65f;
+            mResultList->addColumn(name);
+
+            //LLScrollListColumn::Params time;
+            //time.name="time";
+            //time.header.label="Time";
+            //time.width.relative_width = 0.2f;
+            //mResultList->addColumn(time);
+
+            LLScrollListColumn::Params date;
+            date.name="date";
+            date.header.label="Date";
+            date.width.relative_width = 0.3f;
+            mResultList->addColumn(date);
+            break;
+        }
+        case SE_UNDEFINED:
+        default:
+            LL_WARNS("Search") << "Unhandled search mode: " << mCurrentResultType << LL_ENDL;
+            break;
+
+    }
+}
+
+void LLFloaterDirectory::queryDirectory(const LLDirQuery& query, bool new_search)
+{
+    if (mCurrentResultType != query.type)
+    {
+        mCurrentResultType = query.type;
+        rebuildResultList();
+    }
+    mResultList->clearRows();
+
+    if (new_search)
+    {
+        mResultStart = 0;
+    }
+
+    mCurrentQuery = query;
+    mNumResultsReceived = 0;
+    mQueryID.generate();
+
+    switch (mCurrentResultType)
+    {
+        case SE_PEOPLE:
+        {
+            gMessageSystem->newMessageFast(_PREHASH_DirFindQuery);
+            gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+            gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+            gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+            gMessageSystem->nextBlockFast(_PREHASH_QueryData);
+            gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID);
+            gMessageSystem->addStringFast(_PREHASH_QueryText, query.text);
+            gMessageSystem->addU32Fast(_PREHASH_QueryFlags, DFQ_PEOPLE);
+            gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart);
+            gAgent.sendReliableMessage();
+            LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << LL_ENDL;
+            break;
+        }
+        case SE_GROUPS:
+        {
+            gMessageSystem->newMessageFast(_PREHASH_DirFindQuery);
+            gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+            gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+            gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+            gMessageSystem->nextBlockFast(_PREHASH_QueryData);
+            gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID);
+            gMessageSystem->addStringFast(_PREHASH_QueryText, query.text);
+            gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope);
+            gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart);
+            gAgent.sendReliableMessage();
+            LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << LL_ENDL;
+            break;
+        }
+        case SE_EVENTS:
+        {
+            gMessageSystem->newMessageFast(_PREHASH_DirFindQuery);
+            gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+            gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+            gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+            gMessageSystem->nextBlockFast(_PREHASH_QueryData);
+            gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID);
+            gMessageSystem->addStringFast(_PREHASH_QueryText, query.text);
+            gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope);
+            gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart);
+            gAgent.sendReliableMessage();
+            LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << " Search Text: " << query.text << LL_ENDL;
+            break;
+        }
+        case SE_PLACES:
+        {
+            gMessageSystem->newMessageFast(_PREHASH_DirPlacesQuery);
+            gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+            gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+            gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+            gMessageSystem->nextBlockFast(_PREHASH_QueryData);
+            gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID);
+            gMessageSystem->addStringFast(_PREHASH_QueryText, query.text);
+            gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope);
+            gMessageSystem->addS8Fast(_PREHASH_Category, query.category_char);
+            // TODO: Search filter by region name.
+            gMessageSystem->addStringFast(_PREHASH_SimName, "");
+            gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart);
+            gAgent.sendReliableMessage();
+            LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << LL_ENDL;
+            break;
+        }
+        case SE_LANDSALES:
+        {
+            gMessageSystem->newMessageFast(_PREHASH_DirLandQuery);
+            gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+            gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+            gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+            gMessageSystem->nextBlockFast(_PREHASH_QueryData);
+            gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID);
+            gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope);
+            gMessageSystem->addU32Fast(_PREHASH_SearchType, query.category_int);
+            gMessageSystem->addS32Fast(_PREHASH_Price, query.price);
+            gMessageSystem->addS32Fast(_PREHASH_Area, query.area);
+            gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart);
+            gAgent.sendReliableMessage();
+            LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << query.category_int << LL_ENDL;
+            break;
+        }
+        case SE_CLASSIFIEDS:
+        {
+            gMessageSystem->newMessageFast(_PREHASH_DirClassifiedQuery);
+            gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+            gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+            gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+            gMessageSystem->nextBlockFast(_PREHASH_QueryData);
+            gMessageSystem->addUUIDFast(_PREHASH_QueryID, mQueryID);
+            gMessageSystem->addStringFast(_PREHASH_QueryText, query.text);
+            gMessageSystem->addU32Fast(_PREHASH_QueryFlags, query.scope);
+            gMessageSystem->addU32Fast(_PREHASH_Category, query.category_int);
+            gMessageSystem->addS32Fast(_PREHASH_QueryStart, mResultStart);
+            gAgent.sendReliableMessage();
+            LL_DEBUGS("Search") << "Firing off search request: " << mQueryID << LL_ENDL;
+            break;
+        }
+        case SE_UNDEFINED:
+        default:
+            break;
+    }
+    mResultList->setCommentText(getString("searching"));
+    setProgress(true);
+}
+
+//static
+void LLFloaterDirectory::processSearchPeopleReply(LLMessageSystem* msg, void**)
+{
+    LLUUID query_id;
+    std::string first_name;
+    std::string last_name;
+    LLUUID agent_id;
+    U8 online;
+    //S32 reputation;
+
+    msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id);
+    msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+
+    if (agent_id != gAgent.getID()) return; // not for us
+    LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL;
+
+    // *TODO: Get rid of this so we can have multiple search windows
+    LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search");
+    if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for
+    self->setProgress(false);
+
+    LLScrollListCtrl* pResults = self->mResultList;
+
+    S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
+    if (num_new_rows == 0)
+    {
+        LLStringUtil::format_map_t map;
+        map["[TEXT]"] = self->mCurrentQuery.text;
+        pResults->setCommentText(self->getString("not_found", map));
+    }
+
+    self->mNumResultsReceived += num_new_rows;
+
+    for (S32 i = 0; i < num_new_rows; ++i)
+    {
+        msg->getStringFast( _PREHASH_QueryReplies,  _PREHASH_FirstName, first_name, i);
+        msg->getStringFast( _PREHASH_QueryReplies,  _PREHASH_LastName,  last_name, i);
+        msg->getUUIDFast(   _PREHASH_QueryReplies,  _PREHASH_AgentID,   agent_id, i);
+        //msg->getS32Fast(  _PREHASH_QueryReplies,  _PREHASH_Reputation, reputation, i);
+        msg->getU8Fast(     _PREHASH_QueryReplies,  _PREHASH_Online,    online, i);
+
+        if (agent_id.isNull())
+        {
+            LL_INFOS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL;
+            LLStringUtil::format_map_t map;
+            map["[TEXT]"] = self->mCurrentQuery.text;
+            pResults->setCommentText(self->getString("not_found", map));
+        }
+        else
+        {
+            LL_DEBUGS("Search") << "Got: " << first_name << " " << last_name << " AgentID: " << agent_id << LL_ENDL;
+            pResults->setEnabled(TRUE);
+
+            std::string avatar_name = LLCacheName::buildFullName(first_name, last_name);
+
+            LLSD element;
+            element["id"] = agent_id;
+
+            element["columns"][0]["column"] = "icon";
+            element["columns"][0]["type"]   = "icon";
+            element["columns"][0]["value"]  = online ? "icon_avatar_online.tga" : "icon_avatar_offline.tga";
+
+            element["columns"][1]["column"] = "name";
+            element["columns"][1]["value"]  = avatar_name;
+
+            pResults->addElement(element, ADD_BOTTOM);
+        }
+    }
+    self->paginate();
+}
+
+//static
+void LLFloaterDirectory::processSearchGroupsReply(LLMessageSystem* msg, void**)
+{
+    LLUUID query_id;
+    LLUUID group_id;
+    LLUUID agent_id;
+    std::string group_name;
+    S32 members;
+    F32 search_order;
+
+    msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id);
+    msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+
+    if (agent_id != gAgent.getID()) return; // not for us
+    LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL;
+
+    LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search");
+    if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for
+
+    self->setProgress(false);
+    LLScrollListCtrl* pResults = self->mResultList;
+
+    // Check for status messages
+    if (msg->getNumberOfBlocks("StatusData"))
+    {
+        U32 status;
+        msg->getU32("StatusData", "Status", status);
+        if (status & STATUS_SEARCH_PLACES_FOUNDNONE)
+        {
+            LLStringUtil::format_map_t map;
+            map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString();
+            pResults->setCommentText(self->getString("not_found", map));
+            return;
+        }
+        else if(status & STATUS_SEARCH_PLACES_SHORTSTRING)
+        {
+            pResults->setCommentText(self->getString("search_short"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_PLACES_BANNEDWORD)
+        {
+            pResults->setCommentText(self->getString("search_banned"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED)
+        {
+            pResults->setCommentText(self->getString("search_disabled"));
+            return;
+        }
+    }
+
+    S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
+    if (num_new_rows == 0)
+    {
+        LLStringUtil::format_map_t map;
+        map["[TEXT]"] = self->mCurrentQuery.text;
+        pResults->setCommentText(self->getString("not_found", map));
+    }
+
+    self->mNumResultsReceived += num_new_rows;
+    for (S32 i = 0; i < num_new_rows; ++i)
+    {
+        msg->getUUIDFast(   _PREHASH_QueryReplies,  _PREHASH_GroupID,       group_id,   i);
+        msg->getStringFast( _PREHASH_QueryReplies,  _PREHASH_GroupName,     group_name, i);
+        msg->getS32Fast(    _PREHASH_QueryReplies,  _PREHASH_Members,       members,    i);
+        msg->getF32Fast(    _PREHASH_QueryReplies,  _PREHASH_SearchOrder,   search_order,i);
+        if (group_id.isNull())
+        {
+            LL_DEBUGS("Search") << "No results returned for QueryID: " << query_id << LL_ENDL;
+            LLStringUtil::format_map_t map;
+            map["[TEXT]"] = self->mCurrentQuery.text;
+            pResults->setCommentText(self->getString("not_found", map));
+        }
+        else
+        {
+            LL_DEBUGS("Search") << "Got: " << group_name << " GroupID: " << group_id << LL_ENDL;
+            pResults->setEnabled(TRUE);
+
+            LLSD element;
+
+            element["id"] = group_id;
+
+            element["columns"][0]["column"] = "icon";
+            element["columns"][0]["type"]   = "icon";
+            element["columns"][0]["value"]  = "Icon_Group";
+
+            element["columns"][1]["column"] = "name";
+            element["columns"][1]["value"]  = group_name;
+
+            element["columns"][2]["column"] = "members";
+            element["columns"][2]["value"]  = members;
+
+            element["columns"][3]["column"] = "score";
+            element["columns"][3]["value"]  = search_order;
+
+            pResults->addElement(element, ADD_BOTTOM);
+        }
+    }
+    self->paginate();
+}
+
+//static
+void LLFloaterDirectory::processSearchPlacesReply(LLMessageSystem* msg, void**)
+{
+    LLUUID  agent_id;
+    LLUUID  query_id;
+    LLUUID  parcel_id;
+    std::string name;
+    BOOL    for_sale;
+    BOOL    auction;
+    F32     dwell;
+
+    msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id);
+    msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+
+    if (agent_id != gAgent.getID()) return; // not for us
+    LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL;
+
+    LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search");
+    if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for
+
+    self->setProgress(false);
+    LLScrollListCtrl* pResults = self->mResultList;
+
+    // Check for status messages
+    if (msg->getNumberOfBlocks("StatusData"))
+    {
+        U32 status;
+        msg->getU32("StatusData", "Status", status);
+        if (status & STATUS_SEARCH_PLACES_FOUNDNONE)
+        {
+            LLStringUtil::format_map_t map;
+            map["[TEXT]"] = self->mCurrentQuery.text;
+            pResults->setCommentText(self->getString("not_found", map));
+            return;
+        }
+        else if(status & STATUS_SEARCH_PLACES_SHORTSTRING)
+        {
+            pResults->setCommentText(self->getString("search_short"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_PLACES_BANNEDWORD)
+        {
+            pResults->setCommentText(self->getString("search_banned"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED)
+        {
+            pResults->setCommentText(self->getString("search_disabled"));
+            return;
+        }
+    }
+
+    S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
+    if (num_new_rows == 0)
+    {
+        LLStringUtil::format_map_t map;
+        map["[TEXT]"] = self->mCurrentQuery.text;
+                pResults->setCommentText(self->getString("not_found", map));
+    }
+
+    self->mNumResultsReceived += num_new_rows;
+    for (S32 i = 0; i < num_new_rows; ++i)
+    {
+        msg->getUUID(   "QueryReplies", "ParcelID", parcel_id,  i);
+        msg->getString( "QueryReplies", "Name",     name,       i);
+        msg->getBOOL(   "QueryReplies", "ForSale",  for_sale,   i);
+        msg->getBOOL(   "QueryReplies", "Auction",  auction,    i);
+        msg->getF32(    "QueryReplies", "Dwell",    dwell,      i);
+        if (parcel_id.isNull())
+        {
+            LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL;
+            LLStringUtil::format_map_t map;
+            map["[TEXT]"] = self->mCurrentQuery.text;
+                        pResults->setCommentText(self->getString("not_found", map));
+        }
+        else
+        {
+            LL_DEBUGS("Search") << "Got: " << name << " ParcelID: " << parcel_id << LL_ENDL;
+            pResults->setEnabled(TRUE);
+
+            LLSD element;
+
+            element["id"] = parcel_id;
+
+            if (auction)
+            {
+                element["columns"][0]["column"] = "icon";
+                element["columns"][0]["type"]   = "icon";
+                element["columns"][0]["value"]  = "Icon_Auction";
+            }
+            else if (for_sale)
+            {
+                element["columns"][0]["column"] = "icon";
+                element["columns"][0]["type"]   = "icon";
+                element["columns"][0]["value"]  = "Icon_For_Sale";
+            }
+            else
+            {
+                element["columns"][0]["column"] = "icon";
+                element["columns"][0]["type"]   = "icon";
+                element["columns"][0]["value"]  = "Icon_Place";
+            }
+
+            element["columns"][1]["column"] = "name";
+            element["columns"][1]["value"]  = name;
+
+            std::string buffer = llformat("%.0f", dwell);
+            element["columns"][2]["column"] = "dwell";
+            element["columns"][2]["value"]  = buffer;
+
+            pResults->addElement(element, ADD_BOTTOM);
+        }
+    }
+    self->paginate();
+}
+
+//static
+void LLFloaterDirectory::processSearchClassifiedsReply(LLMessageSystem* msg, void**)
+{
+    LLUUID  agent_id;
+    LLUUID  query_id;
+    LLUUID  classified_id;
+    std::string name;
+    U32     creation_date;
+    U32     expiration_date;
+    S32     price_for_listing;
+
+    msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id);
+    msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+
+    if (agent_id != gAgent.getID()) return; // not for us
+    LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL;
+
+    LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search");
+    if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for
+
+    self->setProgress(false);
+    LLScrollListCtrl* pResults = self->mResultList;
+
+    // Check for status messages
+    if (msg->getNumberOfBlocks("StatusData"))
+    {
+        U32 status;
+        msg->getU32("StatusData", "Status", status);
+        if (status & STATUS_SEARCH_PLACES_FOUNDNONE)
+        {
+            LLStringUtil::format_map_t map;
+            map["[TEXT]"] = self->mCurrentQuery.text;
+            pResults->setCommentText(self->getString("not_found", map));
+            return;
+        }
+        else if(status & STATUS_SEARCH_PLACES_SHORTSTRING)
+        {
+            pResults->setCommentText(self->getString("search_short"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_PLACES_BANNEDWORD)
+        {
+            pResults->setCommentText(self->getString("search_banned"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED)
+        {
+            pResults->setCommentText(self->getString("search_disabled"));
+            return;
+        }
+    }
+
+    S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
+    if (num_new_rows == 0)
+    {
+        LLStringUtil::format_map_t map;
+        map["[TEXT]"] = self->mCurrentQuery.text;
+        pResults->setCommentText(self->getString("not_found", map));
+    }
+
+    self->mNumResultsReceived += num_new_rows;
+    for (S32 i = 0; i < num_new_rows; ++i)
+    {
+        msg->getUUID(   "QueryReplies", "ClassifiedID",     classified_id,  i);
+        msg->getString( "QueryReplies", "Name",             name,           i);
+        msg->getU32(    "QueryReplies", "CreationDate",     creation_date,  i);
+        msg->getU32(    "QueryReplies", "ExpirationDate",   expiration_date,i);
+        msg->getS32(    "QueryReplies", "PriceForListing",  price_for_listing,i);
+        if (classified_id.isNull())
+        {
+            LL_DEBUGS("Search") << "No results returned for QueryID: " << query_id << LL_ENDL;
+            LLStringUtil::format_map_t map;
+            map["[TEXT]"] = self->mCurrentQuery.text;
+                        pResults->setCommentText(self->getString("not_found", map));
+        }
+        else
+        {
+            LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << classified_id << LL_ENDL;
+            pResults->setEnabled(TRUE);
+
+            LLSD element;
+
+            element["id"] = classified_id;
+
+            element["columns"][0]["column"] = "icon";
+            element["columns"][0]["type"]   = "icon";
+            element["columns"][0]["value"]  = "icon_top_pick.tga";
+
+            element["columns"][1]["column"] = "name";
+            element["columns"][1]["value"]  = name;
+
+            element["columns"][2]["column"] = "price";
+            element["columns"][2]["value"]  = price_for_listing;
+
+            pResults->addElement(element, ADD_BOTTOM);
+        }
+    }
+    self->paginate();
+}
+
+// static
+void LLFloaterDirectory::processSearchLandReply(LLMessageSystem* msg, void**)
+{
+    LLUUID  agent_id;
+    LLUUID  query_id;
+    LLUUID  parcel_id;
+    std::string name;
+    std::string land_sku;
+    std::string land_type;
+    BOOL    auction;
+    BOOL    for_sale;
+    S32     price;
+    S32     area;
+
+    msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id);
+    msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+
+    if (agent_id != gAgent.getID()) return; // not for us
+    LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL;
+
+    LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search");
+    if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for
+
+    self->setProgress(false);
+    LLScrollListCtrl* pResults = self->mResultList;
+
+    // Check for status messages
+    if (msg->getNumberOfBlocks("StatusData"))
+    {
+        U32 status;
+        msg->getU32("StatusData", "Status", status);
+        if (status & STATUS_SEARCH_PLACES_FOUNDNONE)
+        {
+            LLStringUtil::format_map_t map;
+            map["[TEXT]"] = self->mCurrentQuery.text;
+            pResults->setCommentText(self->getString("not_found", map));
+            return;
+        }
+        else if(status & STATUS_SEARCH_PLACES_SHORTSTRING)
+        {
+            pResults->setCommentText(self->getString("search_short"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_PLACES_BANNEDWORD)
+        {
+            pResults->setCommentText(self->getString("search_banned"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED)
+        {
+            pResults->setCommentText(self->getString("search_disabled"));
+            return;
+        }
+    }
+
+    S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
+    if (num_new_rows == 0)
+    {
+        LLStringUtil::format_map_t map;
+        map["[TEXT]"] = self->mCurrentQuery.text;
+                pResults->setCommentText(self->getString("not_found", map));
+    }
+
+    self->mNumResultsReceived += num_new_rows;
+    for (S32 i = 0; i < num_new_rows; ++i)
+    {
+        msg->getUUID(   "QueryReplies", "ParcelID",     parcel_id,  i);
+        msg->getString( "QueryReplies", "Name",         name,       i);
+        msg->getBOOL(   "QueryReplies", "Auction",      auction,    i);
+        msg->getBOOL(   "QueryReplies", "ForSale",      for_sale,   i);
+        msg->getS32(    "QueryReplies", "SalePrice",    price,      i);
+        msg->getS32(    "QueryReplies", "ActualArea",   area,       i);
+        if (parcel_id.isNull())
+        {
+            LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL;
+            pResults->setCommentText(self->getString("no_results"));
+        }
+        else
+        {
+            LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << parcel_id << LL_ENDL;
+            pResults->setEnabled(TRUE);
+            if ( msg->getSizeFast(_PREHASH_QueryReplies, i, _PREHASH_ProductSKU) > 0 )
+            {
+                msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_ProductSKU, land_sku, i);
+                land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku);
+            }
+            else
+            {
+                land_sku.clear();
+                land_type = LLTrans::getString("land_type_unknown");
+            }
+            if (parcel_id.isNull())
+                continue;
+
+            LLSD element;
+
+            element["id"] = parcel_id;
+            if (auction)
+            {
+                element["columns"][0]["column"] = "icon";
+                element["columns"][0]["type"]   = "icon";
+                element["columns"][0]["value"]  = "Icon_Auction";
+            }
+            else if (for_sale)
+            {
+                element["columns"][0]["column"] = "icon";
+                element["columns"][0]["type"]   = "icon";
+                element["columns"][0]["value"]  = "Icon_For_Sale";
+            }
+            else
+            {
+                element["columns"][0]["column"] = "icon";
+                element["columns"][0]["type"]   = "icon";
+                element["columns"][0]["value"]  = "Icon_Place";
+            }
+
+            element["columns"][1]["column"] = "name";
+            element["columns"][1]["value"]  = name;
+
+            std::string buffer = "Auction";
+            if (!auction)
+            {
+                buffer = llformat("%d", price);
+            }
+            element["columns"][2]["column"] = "price";
+            element["columns"][2]["value"]  = price;
+
+            element["columns"][3]["column"] = "area";
+            element["columns"][3]["value"]  = area;
+            if (!auction)
+            {
+                F32 ppm;
+                if (area > 0)
+                    ppm = (F32)price / (F32)area;
+                else
+                    ppm = 0.f;
+                std::string buffer = llformat("%.1f", ppm);
+                element["columns"][4]["column"] = "ppm";
+                element["columns"][4]["value"]  = buffer;
+            }
+            else
+            {
+                element["columns"][4]["column"] = "ppm";
+                element["columns"][4]["value"]  = "1.0";
+            }
+
+            element["columns"][5]["column"] = "type";
+            element["columns"][5]["value"]  = land_type;
+
+            pResults->addElement(element, ADD_BOTTOM);
+        }
+    }
+    self->paginate();
+}
+
+// static
+void LLFloaterDirectory::processSearchEventsReply(LLMessageSystem* msg, void**)
+{
+    LLUUID  agent_id;
+    LLUUID  query_id;
+    LLUUID  owner_id;
+    std::string name;
+    std::string date;
+
+    msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id);
+    msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+
+    if (agent_id != gAgent.getID()) return; // not for us
+    LL_DEBUGS("Search") << "Received results for query id: " << query_id << LL_ENDL;
+
+    LLFloaterDirectory* self = LLFloaterReg::findTypedInstance<LLFloaterDirectory>("search");
+    if (self == nullptr || query_id != self->mQueryID) return; // not the result we're waiting for
+
+    self->setProgress(false);
+    LLScrollListCtrl* pResults = self->mResultList;
+
+    // Check for status messages
+    if (msg->getNumberOfBlocks("StatusData"))
+    {
+        U32 status;
+        msg->getU32("StatusData", "Status", status);
+        if (status & STATUS_SEARCH_EVENTS_FOUNDNONE)
+        {
+            LLStringUtil::format_map_t map;
+            map["[TEXT]"] = self->mCurrentQuery.text;
+            pResults->setCommentText(self->getString("not_found", map));
+            return;
+        }
+        else if(status & STATUS_SEARCH_EVENTS_SHORTSTRING)
+        {
+            pResults->setCommentText(self->getString("search_short"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_EVENTS_BANNEDWORD)
+        {
+            pResults->setCommentText(self->getString("search_banned"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_EVENTS_SEARCHDISABLED)
+        {
+            pResults->setCommentText(self->getString("search_disabled"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_EVENTS_NODATEOFFSET)
+        {
+            pResults->setCommentText(self->getString("search_no_date_offset"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_EVENTS_NOCATEGORY)
+        {
+            pResults->setCommentText(self->getString("search_no_events_category"));
+            return;
+        }
+        else if (status & STATUS_SEARCH_EVENTS_NOQUERY)
+        {
+            pResults->setCommentText(self->getString("search_no_query"));
+            return;
+        }
+    }
+
+    S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
+    if (num_new_rows == 0)
+    {
+        LLStringUtil::format_map_t map;
+        map["[TEXT]"] = self->mCurrentQuery.text;
+                pResults->setCommentText(self->getString("not_found", map));
+    }
+
+    self->mNumResultsReceived += num_new_rows;
+    for (S32 i = 0; i < num_new_rows; ++i)
+    {
+        U32 event_id;
+        //U32 unix_time;
+        U32 event_flags;
+
+        msg->getUUID(   "QueryReplies", "OwnerID",      owner_id,   i);
+        msg->getString( "QueryReplies", "Name",         name,       i);
+        msg->getU32(    "QueryReplies", "EventID",      event_id,   i);
+        msg->getString( "QueryReplies", "Date",         date,       i);
+        //msg->getU32(  "QueryReplies", "UnixTime",     unix_time,  i);
+        msg->getU32(    "QueryReplies", "EventFlags",   event_flags,i);
+
+        static LLUICachedControl<bool> inc_pg("ShowPGEvents", true);
+        static LLUICachedControl<bool> inc_mature("ShowMatureEvents", false);
+        static LLUICachedControl<bool> inc_adult("ShowAdultEvents", false);
+
+        // Skip empty events...
+        if (owner_id.isNull())
+        {
+            LL_INFOS("Search") << "Skipped " << event_id << " because of a NULL owner result" << LL_ENDL;
+            continue;
+        }
+        // Skips events that don't match our scope...
+        if (((event_flags & (EVENT_FLAG_ADULT | EVENT_FLAG_MATURE)) == EVENT_FLAG_NONE) && !inc_pg)
+        {
+            LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL;
+            continue;
+        }
+        if ((event_flags & EVENT_FLAG_MATURE) && !inc_mature)
+        {
+            LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL;
+            continue;
+        }
+        if ((event_flags & EVENT_FLAG_ADULT) && !inc_adult)
+        {
+            LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL;
+            continue;
+        }
+        pResults->setEnabled(TRUE);
+
+        LLSD element;
+
+        element["id"] = llformat("%u", event_id);
+
+        if (event_flags == EVENT_FLAG_ADULT)
+        {
+            element["columns"][0]["column"] = "icon";
+            element["columns"][0]["type"] = "icon";
+            element["columns"][0]["value"] = "Parcel_R_Dark";
+        }
+        else if (event_flags == EVENT_FLAG_MATURE)
+        {
+            element["columns"][0]["column"] = "icon";
+            element["columns"][0]["type"] = "icon";
+            element["columns"][0]["value"] = "Parcel_M_Dark";
+        }
+        else
+        {
+            element["columns"][0]["column"] = "icon";
+            element["columns"][0]["type"] = "icon";
+            element["columns"][0]["value"] = "Parcel_PG_Dark";
+        }
+
+        element["columns"][1]["column"] = "name";
+        element["columns"][1]["value"] = name;
+
+        element["columns"][2]["column"] = "date";
+        element["columns"][2]["value"] = date;
+
+        //element["columns"][3]["column"] = "time";
+        //element["columns"][3]["value"] = llformat("%u", unix_time);
+
+        pResults->addElement(element, ADD_BOTTOM);
+    }
+    self->paginate();
+}
diff --git a/indra/newview/llfloaterdirectory.h b/indra/newview/llfloaterdirectory.h
new file mode 100644
index 0000000000000000000000000000000000000000..0817f223ab432cc88409a3bda40df146d6d8075f
--- /dev/null
+++ b/indra/newview/llfloaterdirectory.h
@@ -0,0 +1,134 @@
+/*
+ * @file llfloaterdirectory.h
+ * @brief Legacy search facility definitions
+ *
+ * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_FLOATERDIRECTORY_H
+#define LL_FLOATERDIRECTORY_H
+
+#include "llfloater.h"
+#include "llsdparam.h"
+
+class LLUICtrl;
+class LLPanel;
+class LLPanelSearchWeb;
+class LLScrollListCtrl;
+class LLTabContainer;
+class LLTextBase;
+
+static const size_t MIN_SEARCH_STRING_SIZE = 3;
+
+typedef enum {
+    SE_UNDEFINED = 0,
+    SE_PEOPLE,
+    SE_GROUPS,
+    SE_PLACES,
+    SE_LANDSALES,
+    SE_EVENTS,
+    SE_CLASSIFIEDS
+} ESearch;
+
+struct SearchQuery : public LLInitParam::Block<SearchQuery>
+{
+    Optional<std::string> category;
+    Optional<std::string> collection;
+    Optional<std::string> query;
+
+    SearchQuery();
+};
+
+typedef struct dir_query
+{
+    dir_query()
+        : type(SE_UNDEFINED), text(LLStringUtil::null), scope(0),
+        category_int(0), category_char(0x0), price(0), area(0), results_per_page(100) {}
+    ESearch type;
+    std::string text;
+    U32 scope;
+    U32 category_int;
+    S8 category_char;
+    S32 price;
+    S32 area;
+    U32 results_per_page;
+} LLDirQuery;
+
+class LLFloaterDirectory : public LLFloater
+{
+    friend class LLPanelSearchClassifieds;
+    friend class LLPanelSearchEvents;
+    friend class LLPanelSearchGroups;
+    friend class LLPanelSearchLandSales;
+    friend class LLPanelSearchPeople;
+    friend class LLPanelSearchPlaces;
+
+public:
+    struct _Params : LLInitParam::Block<_Params, LLFloater::Params>
+    {
+        Optional<SearchQuery> search;
+    };
+    typedef LLSDParamAdapter<_Params> Params;
+
+    LLFloaterDirectory(const Params& key);
+    BOOL postBuild() override;
+    void onOpen(const LLSD& key) override;
+    void onClose(bool app_quitting) override;
+
+    static void processSearchPeopleReply(LLMessageSystem* msg, void**);
+    static void processSearchGroupsReply(LLMessageSystem* msg, void**);
+    static void processSearchPlacesReply(LLMessageSystem* msg, void**);
+    static void processSearchClassifiedsReply(LLMessageSystem* msg, void**);
+    static void processSearchLandReply(LLMessageSystem* msg, void**);
+    static void processSearchEventsReply(LLMessageSystem* msg, void**);
+
+protected:
+    void setProgress(bool working);
+    void queryDirectory(const LLDirQuery& query, bool new_search = false);
+    void setResultsComment(const std::string& message);
+
+private:
+    ~LLFloaterDirectory();
+    void onCommitSelection();
+    void choosePage(LLUICtrl* ctrl);
+    void onTabChanged();
+    void paginate();
+    void showDetailPanel(const std::string& panel_name);
+    void rebuildResultList();
+
+    ESearch mCurrentResultType;
+    LLDirQuery mCurrentQuery;
+    S32 mResultStart;
+    S32 mNumResultsReceived;
+    LLUUID mQueryID;
+
+    LLTabContainer* mTabContainer;
+    LLPanelSearchWeb* mPanelWeb;
+    LLScrollListCtrl* mResultList;
+    LLTextBase* mResultsStatus;
+};
+
+#endif // LL_FLOATERDIRECTORY_H
diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp
index b07f2963b270439d8b2c59e12be7d8169f6368e0..92d762fa9cb37bcfe3abca4e7d4bbc33cb013ee4 100644
--- a/indra/newview/llfloaterevent.cpp
+++ b/indra/newview/llfloaterevent.cpp
@@ -3,8 +3,9 @@
  * @brief Display for events in the finder
  *
  * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
+ * Alchemy Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2014, Cinder Roxley @ Second Life
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,93 +28,20 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llfloaterevent.h"
-
-#include "message.h"
-#include "llnotificationsutil.h"
-#include "llui.h"
-
-#include "llagent.h"
-#include "llviewerwindow.h"
-#include "llbutton.h"
-#include "llcachename.h"
-#include "llcommandhandler.h"   // secondlife:///app/chat/ support
-#include "lleventflags.h"
-#include "llmediactrl.h"
-#include "llexpandabletextbox.h"
-#include "llfloater.h"
-#include "llfloaterreg.h"
-#include "llmediactrl.h"
-#include "llfloaterworldmap.h"
-#include "llinventorymodel.h"
-#include "llslurl.h"
-#include "lltextbox.h"
-#include "lltexteditor.h"
-#include "lluiconstants.h"
-#include "llviewercontrol.h"
-#include "llweb.h"
-#include "llworldmap.h"
-#include "llworldmapmessage.h"
-#include "lluictrlfactory.h"
-#include "lltrans.h"
+#include "llpaneleventinfo.h"
 
 
 LLFloaterEvent::LLFloaterEvent(const LLSD& key)
-    : LLFloater(key),
-      LLViewerMediaObserver(),
-      mBrowser(NULL),
-      mEventID(0)
-{
-}
-
-
-LLFloaterEvent::~LLFloaterEvent()
-{
-}
-
-
-BOOL LLFloaterEvent::postBuild()
+:   LLFloater(key)
+,   mEventId(0)
 {
-    mBrowser = getChild<LLMediaCtrl>("browser");
-    if (mBrowser)
-    {
-        mBrowser->addObserver(this);
-    }
 
-    return TRUE;
-}
-
-void LLFloaterEvent::handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event)
-{
-    switch (event)
-    {
-        case MEDIA_EVENT_NAVIGATE_BEGIN:
-            getChild<LLUICtrl>("status_text")->setValue(getString("loading_text"));
-            break;
-
-        case MEDIA_EVENT_NAVIGATE_COMPLETE:
-            getChild<LLUICtrl>("status_text")->setValue(getString("done_text"));
-            break;
-
-        default:
-            break;
-    }
 }
 
 void LLFloaterEvent::setEventID(const U32 event_id)
 {
-    mEventID = event_id;
-
-    if (event_id != 0)
-    {
-        LLSD subs;
-        subs["EVENT_ID"] = (S32)event_id;
-        // get the search URL and expand all of the substitutions
-        // (also adds things like [LANGUAGE], [VERSION], [OS], etc.)
-
-        std::string expanded_url = LLWeb::expandURLSubstitutions(gSavedSettings.getString("EventURL"), subs);
-
-        // and load the URL in the web view
-        mBrowser->navigateTo(expanded_url);
+    mEventId = event_id;
+    if (event_id == 0) closeFloater();
 
-    }
+    getChild<LLPanel>("event_panel")->onOpen(mEventId);
 }
diff --git a/indra/newview/llfloaterevent.h b/indra/newview/llfloaterevent.h
index 169ce246ecb5c1ba902a1f8de0e6096ddfa97c0e..50eb86e07cbf7c0bb9193cd935d103c1ca2c09d5 100644
--- a/indra/newview/llfloaterevent.h
+++ b/indra/newview/llfloaterevent.h
@@ -3,8 +3,9 @@
  * @brief Display for events in the finder
  *
  * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
+ * Alchemy Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2014, Cinder Roxley @ Second Life
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -28,35 +29,17 @@
 #define LL_LLFLOATEREVENT_H
 
 #include "llfloater.h"
-#include "llviewermediaobserver.h"
 
-
-class LLMediaCtrl;
-class LLButton;
-
-class LLFloaterEvent final : public LLFloater,
-                       public LLViewerMediaObserver
+class LLFloaterEvent final : public LLFloater
 
 {
 public:
     LLFloaterEvent(const LLSD& key);
-    /*virtual*/ ~LLFloaterEvent();
-
-    /*virtual*/ BOOL postBuild();
-
+    /*virtual*/ ~LLFloaterEvent() = default;
     void setEventID(const U32 event_id);
 
-    U32 getEventID() { return mEventID; }
-
-
-
-protected:
-    /*virtual*/ void handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event);
-
-    U32             mEventID;
-
-    LLMediaCtrl*    mBrowser;
-
+private:
+    S32 mEventId;
 };
 
 #endif // LL_LLFLOATEREVENT_H
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index c3bc8e2f2b3703e11a4b907caa151f8f27c29598..03e587e38eea87ca46551b3a7c45cfb20c7708c9 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -134,15 +134,15 @@ void LLFloaterJoystick::draw()
         }
     }
 
-    for (U32 i = 0; i < 16; i++)
-    {
+	for (U32 i = 0; i < 16; i++)
+	{
         U32 value = joystick->getJoystickButton(i);
-        if (!mAxisButton[i]->getEnabled() && value)
-        {
-            mAxisButton[i]->setEnabled(TRUE);
-        }
-        mAxisButton[i]->setToggleState(value);
-    }
+		if (!mAxisButton[i]->getEnabled() && value)
+		{
+			mAxisButton[i]->setEnabled(TRUE);
+		}
+		mAxisButton[i]->setToggleState(value);
+	}
     LLFloater::draw();
 }
 
@@ -163,11 +163,11 @@ BOOL LLFloaterJoystick::postBuild()
         }
     }
 
-    for (U32 i = 0; i < 16; i++)
-    {
-        std::string btn_name = llformat("btn%d", i);
-        mAxisButton[i] = getChild<LLButton>(btn_name);
-    }
+	for (U32 i = 0; i < 16; i++)
+	{
+		std::string btn_name = llformat("btn%d", i);
+		mAxisButton[i] = getChild<LLButton>(btn_name);
+	}
 
     mJoysticksCombo = getChild<LLComboBox>("joystick_combo");
     childSetCommitCallback("joystick_combo",onCommitJoystickEnabled,this);
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index ebc1a26190cec024421a637ab7749b83f11e25f3..5aa0dbd0104d957ff1f9e98531b4a095dde2872b 100644
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -101,7 +101,7 @@ class LLFloaterJoystick final : public LLFloater
     // stats view
     LLStatBar* mAxisStatsBar[6];
 
-    LLButton* mAxisButton[16];
+	LLButton* mAxisButton[16];
 };
 
 #endif
diff --git a/indra/newview/llfloaterprofilelegacy.cpp b/indra/newview/llfloaterprofilelegacy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..78df15de899971f367e5c2dff917f83d16f1e3a1
--- /dev/null
+++ b/indra/newview/llfloaterprofilelegacy.cpp
@@ -0,0 +1,81 @@
+/*
+ * @file llfloaterprofilelegacy.cpp
+ * @brief Floater that holds panel don't bitch about it, Dog; Merging is easy.
+ *
+ * Copyright (c) 2017-2022, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterprofilelegacy.h"
+
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
+#include "llpanelprofilelegacy.h"
+
+LLFloaterProfileLegacy::LLFloaterProfileLegacy(LLSD const& key)
+:   LLFloater(key)
+{
+
+}
+
+LLFloaterProfileLegacy::~LLFloaterProfileLegacy()
+{
+    if (mAvatarNameCacheConnection.connected())
+        mAvatarNameCacheConnection.disconnect();
+}
+
+BOOL LLFloaterProfileLegacy::postBuild()
+{
+    mPanel = dynamic_cast<LLPanelProfileLegacy*>(getChild<LLPanel>("panel_profile_legacy_sidetray"));
+    return TRUE;
+}
+
+void LLFloaterProfileLegacy::onOpen(const LLSD& key)
+{
+    if (!key.has("avatar_id")) return;
+    const LLUUID av_id = key["avatar_id"].asUUID();
+
+    mAvatarNameCacheConnection = LLAvatarNameCache::get(av_id,
+        boost::bind(&LLFloaterProfileLegacy::onAvatarNameCache, this, _1, _2));
+
+    if (mPanel) { mPanel->onOpen(key); }
+}
+
+void LLFloaterProfileLegacy::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+    setTitle(av_name.getCompleteName());
+    mAvatarNameCacheConnection.disconnect();
+}
+
+LLPanel* LLFloaterProfileLegacy::expandTab(const std::string& name) const
+{
+    return mPanel != nullptr ? mPanel->expandTab(name) : nullptr;
+}
+
+LLPanel* LLFloaterProfileLegacy::getExpandedTab() const
+{
+    return mPanel != nullptr ? mPanel->getExpandedTab() : nullptr;
+}
diff --git a/indra/newview/llfloaterprofilelegacy.h b/indra/newview/llfloaterprofilelegacy.h
new file mode 100644
index 0000000000000000000000000000000000000000..59c9381fd8640ba8bc56931e383b92220cdf4d79
--- /dev/null
+++ b/indra/newview/llfloaterprofilelegacy.h
@@ -0,0 +1,58 @@
+/*
+* @file llfloaterlegacyprofile.h
+* @brief Floater that holds panel
+*
+* Copyright (c) 2017-2022, Cinder Roxley <cinder@sdf.org>
+*
+* Permission is hereby granted, free of charge, to any person or organization
+* obtaining a copy of the software and accompanying documentation covered by
+* this license (the "Software") to use, reproduce, display, distribute,
+* execute, and transmit the Software, and to prepare derivative works of the
+* Software, and to permit third-parties to whom the Software is furnished to
+* do so, all subject to the following:
+*
+* The copyright notices in the Software and this entire statement, including
+* the above license grant, this restriction and the following disclaimer,
+* must be included in all copies of the Software, in whole or in part, and
+* all derivative works of the Software, unless such copies or derivative
+* works are solely in the form of machine-executable object code generated by
+* a source language processor.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*
+*/
+
+#ifndef LL_FLOATERLEGACYPROFILE_H
+#define LL_FLOATERLEGACYPROFILE_H
+
+#include "llfloater.h"
+
+class LLAvatarName;
+class LLPanelProfileLegacy;
+class LLPanelProfileLegacyTab;
+
+class LLFloaterProfileLegacy final : public LLFloater
+{
+public:
+    LLFloaterProfileLegacy(LLSD const& key);
+    BOOL postBuild() override;
+    void onOpen(const LLSD& key) override;
+
+    LLPanel* expandTab(const std::string& name) const;
+    LLPanel* getExpandedTab() const;
+
+private:
+    ~LLFloaterProfileLegacy() override;
+    void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+    LLPanelProfileLegacy* mPanel;
+    boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+#endif // LL_FLOATERLEGACYPROFILE_H
diff --git a/indra/newview/llfloaterpublishclassified.cpp b/indra/newview/llfloaterpublishclassified.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b19cc8f97e2f33d3549a67054591561219116a49
--- /dev/null
+++ b/indra/newview/llfloaterpublishclassified.cpp
@@ -0,0 +1,63 @@
+/**
+ * @file llfloaterpublishclassified.cpp
+ * @brief Publish classified floater
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterpublishclassified.h"
+
+LLFloaterPublishClassified::LLFloaterPublishClassified(const LLSD& key)
+    : LLFloater(key)
+{
+}
+
+BOOL LLFloaterPublishClassified::postBuild()
+{
+    LLFloater::postBuild();
+
+    childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
+    childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
+
+    return TRUE;
+}
+
+void LLFloaterPublishClassified::setPrice(S32 price)
+{
+    getChild<LLUICtrl>("price_for_listing")->setValue(price);
+}
+
+S32 LLFloaterPublishClassified::getPrice()
+{
+    return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
+}
+
+void LLFloaterPublishClassified::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
+{
+    getChild<LLButton>("publish_btn")->setClickedCallback(cb);
+}
+
+void LLFloaterPublishClassified::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
+{
+    getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
+}
diff --git a/indra/newview/llfloaterpublishclassified.h b/indra/newview/llfloaterpublishclassified.h
new file mode 100644
index 0000000000000000000000000000000000000000..f5d79656119eb3c212d9fa0f5369f91188a2ff9b
--- /dev/null
+++ b/indra/newview/llfloaterpublishclassified.h
@@ -0,0 +1,48 @@
+/**
+ * @file llfloaterpublishclassified.h
+ * @brief Publish classified floater
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_PUBLISHCLASSIFIEDFLOATER_H
+#define LL_PUBLISHCLASSIFIEDFLOATER_H
+
+#include "llfloater.h"
+
+class LLFloaterPublishClassified final : public LLFloater
+{
+public:
+    LLFloaterPublishClassified(const LLSD& key);
+    ~LLFloaterPublishClassified() override = default;
+
+    BOOL postBuild() override;
+
+    void setPrice(S32 price);
+    S32 getPrice();
+
+    void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
+    void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
+};
+
+#endif // LL_PUBLISHCLASSIFIEDFLOATER_H
diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..05ec0028548ba3ba2c5c91034f428f46af3d6fa8
--- /dev/null
+++ b/indra/newview/llfloaterwebprofile.cpp
@@ -0,0 +1,81 @@
+/**
+ * @file llfloaterwebprofile.cpp
+ * @brief Web profile floater.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterwebprofile.h"
+
+#include "llviewercontrol.h"
+
+LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) :
+    LLFloaterWebContent(key)
+{
+}
+
+void LLFloaterWebProfile::onOpen(const LLSD& key)
+{
+    Params p(key);
+    p.show_chrome(true);
+    p.window_class("web_content");
+    p.allow_address_entry(false);
+    p.trusted_content(true);
+    LLFloaterWebContent::onOpen(p);
+    applyPreferredRect();
+}
+
+// virtual
+void LLFloaterWebProfile::handleReshape(const LLRect& new_rect, bool by_user)
+{
+    LL_DEBUGS() << "handleReshape: " << new_rect << LL_ENDL;
+
+    if (by_user && !isMinimized())
+    {
+        LL_DEBUGS() << "Storing new rect" << LL_ENDL;
+        gSavedSettings.setRect("WebProfileFloaterRect", new_rect);
+    }
+
+    LLFloaterWebContent::handleReshape(new_rect, by_user);
+}
+
+LLFloater* LLFloaterWebProfile::create(const LLSD& key)
+{
+    LLFloaterWebContent::Params p(key);
+    preCreate(p);
+    return new LLFloaterWebProfile(p);
+}
+
+void LLFloaterWebProfile::applyPreferredRect()
+{
+    const LLRect preferred_rect = gSavedSettings.getRect("WebProfileFloaterRect");
+    LL_DEBUGS() << "Applying preferred rect: " << preferred_rect << LL_ENDL;
+
+    // Don't override position that may have been set by floater stacking code.
+    LLRect new_rect = getRect();
+    new_rect.setLeftTopAndSize(
+        new_rect.mLeft, new_rect.mTop,
+        preferred_rect.getWidth(), preferred_rect.getHeight());
+    setShape(new_rect);
+}
diff --git a/indra/newview/llfloaterwebprofile.h b/indra/newview/llfloaterwebprofile.h
new file mode 100644
index 0000000000000000000000000000000000000000..df9ebc892850144353c0c85da8849a664433da4e
--- /dev/null
+++ b/indra/newview/llfloaterwebprofile.h
@@ -0,0 +1,56 @@
+/**
+ * @file llfloaterwebprofile.h
+ * @brief Web profile floater.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERWEBPROFILE_H
+#define LL_LLFLOATERWEBPROFILE_H
+
+#include "llfloaterwebcontent.h"
+#include "llviewermediaobserver.h"
+
+class LLMediaCtrl;
+
+/**
+ * Displays avatar profile web page.
+ */
+class LLFloaterWebProfile final
+:   public LLFloaterWebContent
+{
+    LOG_CLASS(LLFloaterWebProfile);
+public:
+    typedef LLFloaterWebContent::Params Params;
+
+    LLFloaterWebProfile(const Params& key);
+
+    /*virtual*/ void onOpen(const LLSD& key) override;
+    /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false) override;
+
+    static LLFloater* create(const LLSD& key);
+
+private:
+    void applyPreferredRect();
+};
+
+#endif  // LL_LLFLOATERWEBPROFILE_H
diff --git a/indra/newview/llhudeffectresetskeleton.h b/indra/newview/llhudeffectresetskeleton.h
index 39a613705481319a639700c194faafe8b5a750ee..ddac84165f39ec24521b1f8dc17e09920c24cd9e 100644
--- a/indra/newview/llhudeffectresetskeleton.h
+++ b/indra/newview/llhudeffectresetskeleton.h
@@ -1,25 +1,25 @@
-/**
+/** 
  * @file llhudeffectresetskeleton.h
  * @brief LLHUDEffectResetSkeleton class definition
  *
  * $LicenseInfo:firstyear=2024&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2024, Linden Research, Inc.
- *
+ * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- *
+ * 
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- *
+ * 
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
+ * 
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -36,24 +36,24 @@ class LLVOAvatar;
 class LLHUDEffectResetSkeleton final : public LLHUDEffect
 {
 public:
-    friend class LLHUDObject;
+	friend class LLHUDObject;
 
-    /*virtual*/ void markDead();
-    /*virtual*/ void setSourceObject(LLViewerObject* objectp);
+	/*virtual*/ void markDead();
+	/*virtual*/ void setSourceObject(LLViewerObject* objectp);
 
-    void setTargetObject(LLViewerObject *objp);
-    void setResetAnimations(bool enable){ mResetAnimations = enable; };
+	void setTargetObject(LLViewerObject *objp);
+	void setResetAnimations(bool enable){ mResetAnimations = enable; };
 
 protected:
-    LLHUDEffectResetSkeleton(const U8 type);
-    ~LLHUDEffectResetSkeleton();
+	LLHUDEffectResetSkeleton(const U8 type);
+	~LLHUDEffectResetSkeleton();
 
-    /*virtual*/ void packData(LLMessageSystem *mesgsys);
-    /*virtual*/ void unpackData(LLMessageSystem *mesgsys, S32 blocknum);
+	/*virtual*/ void packData(LLMessageSystem *mesgsys);
+	/*virtual*/ void unpackData(LLMessageSystem *mesgsys, S32 blocknum);
 
-    void update();
+	void update();
 private:
-    bool                        mResetAnimations;
+	bool						mResetAnimations;
 };
 
 #endif // LL_LLHUDEFFECTRESETSKELETON_H
diff --git a/indra/newview/llpanelavatarlegacy.cpp b/indra/newview/llpanelavatarlegacy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c0a943b6757998982ebb0869f80cc034782aa329
--- /dev/null
+++ b/indra/newview/llpanelavatarlegacy.cpp
@@ -0,0 +1,109 @@
+/**
+ * @file llpanelavatarlegacy.cpp
+ * @brief LLPanelAvatar and related class implementations
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelavatarlegacy.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llcallingcard.h"
+
+#include "llscrollcontainer.h"
+#include "llavatariconctrl.h"
+#include "lltextbox.h"
+
+LLPanelProfileLegacyTab::LLPanelProfileLegacyTab()
+: LLPanel()
+, mAvatarId(LLUUID::null)
+{
+}
+
+LLPanelProfileLegacyTab::~LLPanelProfileLegacyTab()
+{
+    if(getAvatarId().notNull())
+    {
+        LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
+    }
+}
+
+void LLPanelProfileLegacyTab::setAvatarId(const LLUUID& id)
+{
+    if(id.notNull())
+    {
+        if(getAvatarId().notNull())
+        {
+            LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this);
+        }
+        mAvatarId = id;
+        LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this);
+    }
+}
+
+void LLPanelProfileLegacyTab::onOpen(const LLSD& key)
+{
+    // Don't reset panel if we are opening it for same avatar.
+    if(getAvatarId() != key.asUUID())
+    {
+        resetControls();
+        resetData();
+
+        scrollToTop();
+    }
+
+    // Update data even if we are viewing same avatar profile as some data might been changed.
+    setAvatarId(key.asUUID());
+    updateData();
+    updateButtons();
+}
+
+void LLPanelProfileLegacyTab::scrollToTop() const
+{
+    LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
+    if (scrollContainer)
+        scrollContainer->goToTop();
+}
+
+void LLPanelProfileLegacyTab::onMapButtonClick()
+{
+    LLAvatarActions::showOnMap(getAvatarId());
+}
+
+void LLPanelProfileLegacyTab::updateButtons()
+{
+    bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId());
+
+    if(LLAvatarActions::isFriend(getAvatarId()))
+    {
+        getChildView("teleport")->setEnabled(is_buddy_online);
+    }
+    else
+    {
+        getChildView("teleport")->setEnabled(true);
+    }
+
+    bool enable_map_btn = (is_buddy_online && LLAvatarActions::isAgentMappable(getAvatarId())) || gAgent.isGodlike();
+    getChildView("show_on_map_btn")->setEnabled(enable_map_btn);
+}
diff --git a/indra/newview/llpanelavatarlegacy.h b/indra/newview/llpanelavatarlegacy.h
new file mode 100644
index 0000000000000000000000000000000000000000..ef442b16bc55eb98eaa4569d48bee9ff00d79830
--- /dev/null
+++ b/indra/newview/llpanelavatarlegacy.h
@@ -0,0 +1,105 @@
+/**
+ * @file llpanelavatarlegacy.h
+ * @brief LLPanelAvatar and related class definitions
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELAVATARLEGACY_H
+#define LL_LLPANELAVATARLEGACY_H
+
+#include "llpanel.h"
+#include "llavatarpropertiesprocessor.h"
+
+class LLComboBox;
+class LLLineEditor;
+
+/**
+* Base class for any Profile View.
+*/
+class LLPanelProfileLegacyTab
+    : public LLPanel
+    , public LLAvatarPropertiesObserver
+{
+public:
+
+    /**
+     * Sets avatar ID, sets panel as observer of avatar related info replies from server.
+     */
+    virtual void setAvatarId(const LLUUID& id);
+
+    /**
+     * Returns avatar ID.
+     */
+    virtual const LLUUID& getAvatarId() { return mAvatarId; }
+
+    /**
+     * Sends update data request to server.
+     */
+    virtual void updateData() = 0;
+
+    /**
+     * Clears panel data if viewing avatar info for first time and sends update data request.
+     */
+    void onOpen(const LLSD& key) override;
+
+    /**
+     * Profile tabs should close any opened panels here.
+     *
+     * Called from LLPanelProfile::onOpen() before opening new profile.
+     * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel
+     * before new profile is displayed, otherwise new profile will
+     * be hidden behind picture info panel.
+     */
+    virtual void onClosePanel() {}
+
+    /**
+     * Resets controls visibility, state, etc.
+     */
+    virtual void resetControls(){};
+
+    /**
+     * Clears all data received from server.
+     */
+    virtual void resetData(){};
+
+    ~LLPanelProfileLegacyTab() override;
+
+protected:
+
+    LLPanelProfileLegacyTab();
+
+    /**
+     * Scrolls panel to top when viewing avatar info for first time.
+     */
+    void scrollToTop() const;
+
+    virtual void onMapButtonClick();
+
+    virtual void updateButtons();
+
+private:
+
+    LLUUID mAvatarId;
+};
+
+#endif // LL_LLPANELAVATARLEGACY_H
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 11d12394592d427b73b3ff85c0432f98446ddee7..b8b95fc711a8e3692df07413770a14e96d4958e0 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -34,21 +34,32 @@
 
 #include "lldispatcher.h"
 #include "llfloaterreg.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
 #include "llparcel.h"
 
 #include "llagent.h"
 #include "llclassifiedflags.h"
+#include "llclassifiedinfo.h"
 #include "lliconctrl.h"
+#include "lllineeditor.h"
+#include "llcombobox.h"
+#include "lllogininstance.h"
 #include "lltexturectrl.h"
+#include "lltexteditor.h"
+#include "llviewerparcelmgr.h"
 #include "llfloaterworldmap.h"
 #include "llviewergenericmessage.h" // send_generic_message
 #include "llviewerregion.h"
+#include "llviewertexture.h"
+#include "lltrans.h"
 #include "llscrollcontainer.h"
+#include "llstatusbar.h"
 #include "llcorehttputil.h"
 
 //static
 LLPanelClassifiedInfo::panel_list_t LLPanelClassifiedInfo::sAllPanels;
-static LLPanelInjector<LLPanelClassifiedInfo> t_panel_panel_classified_info("panel_classified_info");
+static LLPanelInjector<LLPanelClassifiedInfo> t_panel_classified_info("panel_classified_info");
 
 // "classifiedclickthrough"
 // strings[0] = classified_id
@@ -82,6 +93,8 @@ static LLDispatchClassifiedClickThrough sClassifiedClickThrough;
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
+static LLPanelInjector<LLPanelClassifiedInfo> t_classified_info("panel_classified_info");
+
 LLPanelClassifiedInfo::LLPanelClassifiedInfo()
  : LLPanel()
  , mInfoLoaded(false)
@@ -103,6 +116,10 @@ LLPanelClassifiedInfo::LLPanelClassifiedInfo()
 
 LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
 {
+    if (getAvatarId().notNull())
+    {
+        LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+    }
     sAllPanels.remove(this);
 
     if (getAvatarId().notNull())
@@ -111,8 +128,17 @@ LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
     }
 }
 
+// static
+LLPanelClassifiedInfo* LLPanelClassifiedInfo::create()
+{
+    LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo();
+    panel->buildFromFile("panel_classified_info.xml");
+    return panel;
+}
+
 BOOL LLPanelClassifiedInfo::postBuild()
 {
+    childSetAction("back_btn", boost::bind(&LLPanelClassifiedInfo::onExit, this));
     childSetAction("show_on_map_btn", boost::bind(&LLPanelClassifiedInfo::onMapClick, this));
     childSetAction("teleport_btn", boost::bind(&LLPanelClassifiedInfo::onTeleportClick, this));
 
@@ -128,6 +154,16 @@ BOOL LLPanelClassifiedInfo::postBuild()
     return TRUE;
 }
 
+void LLPanelClassifiedInfo::setExitCallback(const commit_callback_t& cb)
+{
+    getChild<LLButton>("back_btn")->setClickedCallback(cb);
+}
+
+void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb)
+{
+    getChild<LLButton>("edit_btn")->setClickedCallback(cb);
+}
+
 void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
 {
     LLPanel::reshape(width, height, called_from_parent);
@@ -156,7 +192,7 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key)
     LLUUID avatar_id = key["classified_creator_id"];
     if(avatar_id.isNull())
     {
-        return;
+        //return;
     }
 
     if(getAvatarId().notNull())
@@ -180,6 +216,7 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key)
 
     LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
     LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+
     gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough);
 
     if (gAgent.getRegion())
@@ -259,9 +296,11 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t
             LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->creation_date));
             getChild<LLUICtrl>("creation_date")->setValue(date_str);
 
-            setInfoLoaded(true);
+            date_str = date_fmt;
+            LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->expiration_date));
+            getChild<LLUICtrl>("expiration_date")->setValue(date_str);
 
-            LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+            setInfoLoaded(true);
         }
     }
 }
@@ -372,9 +411,8 @@ void LLPanelClassifiedInfo::setClickThrough(
             << teleport << ", " << map << ", " << profile << "] ("
             << (from_new_table ? "new" : "old") << ")" << LL_ENDL;
 
-    for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
+    for (auto self : sAllPanels)
     {
-        LLPanelClassifiedInfo* self = *iter;
         if (self->getClassifiedId() != classified_id)
         {
             continue;
@@ -566,4 +604,551 @@ void LLPanelClassifiedInfo::onTeleportClick()
     }
 }
 
-//EOF
+void LLPanelClassifiedInfo::onExit()
+{
+    LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+    gGenericDispatcher.addHandler("classifiedclickthrough", nullptr); // deregister our handler
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+static const S32 CB_ITEM_MATURE = 0;
+static const S32 CB_ITEM_PG    = 1;
+
+LLPanelClassifiedEdit::LLPanelClassifiedEdit()
+ : LLPanelClassifiedInfo()
+ , mIsNew(false)
+ , mIsNewWithErrors(false)
+ , mCanClose(false)
+ , mPublishFloater(nullptr)
+{
+}
+
+LLPanelClassifiedEdit::~LLPanelClassifiedEdit()
+{
+}
+
+//static
+LLPanelClassifiedEdit* LLPanelClassifiedEdit::create()
+{
+    LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit();
+    panel->buildFromFile("panel_edit_classified.xml");
+    return panel;
+}
+
+BOOL LLPanelClassifiedEdit::postBuild()
+{
+    LLPanelClassifiedInfo::postBuild();
+
+    LLUICtrl* edit_icon = getChild<LLUICtrl>("edit_icon");
+    mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
+    mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
+    edit_icon->setVisible(false);
+
+    LLLineEditor* line_edit = getChild<LLLineEditor>("classified_name");
+    line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), nullptr);
+
+    LLTextEditor* text_edit = getChild<LLTextEditor>("classified_desc");
+    text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
+
+    LLComboBox* combobox = getChild<LLComboBox>( "category");
+    LLClassifiedInfo::cat_map::iterator iter;
+    for (iter = LLClassifiedInfo::sCategories.begin();
+        iter != LLClassifiedInfo::sCategories.end();
+        iter++)
+    {
+        combobox->add(LLTrans::getString(iter->second));
+    }
+
+    combobox->setCommitCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
+
+    childSetCommitCallback("content_type", boost::bind(&LLPanelClassifiedEdit::onChange, this), nullptr);
+    childSetCommitCallback("price_for_listing", boost::bind(&LLPanelClassifiedEdit::onChange, this), nullptr);
+    childSetCommitCallback("auto_renew", boost::bind(&LLPanelClassifiedEdit::onChange, this), nullptr);
+
+    childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this));
+    childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this));
+
+    mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onTextureSelected, this));
+
+    return TRUE;
+}
+
+void LLPanelClassifiedEdit::fillIn(const LLSD& key)
+{
+    setAvatarId(gAgent.getID());
+
+    if(key.isUndefined())
+    {
+        setPosGlobal(gAgent.getPositionGlobal());
+
+        LLUUID snapshot_id = LLUUID::null;
+        std::string desc;
+        LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
+        if(parcel)
+        {
+            desc = parcel->getDesc();
+            snapshot_id = parcel->getSnapshotID();
+        }
+
+        std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+        LLViewerRegion* region = gAgent.getRegion();
+        if (region)
+        {
+            region_name = region->getName();
+        }
+
+        getChild<LLUICtrl>("classified_name")->setValue(makeClassifiedName());
+        getChild<LLUICtrl>("classified_desc")->setValue(desc);
+        setSnapshotId(snapshot_id);
+        setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+        // server will set valid parcel id
+        setParcelId(LLUUID::null);
+    }
+    else
+    {
+        setClassifiedId(key["classified_id"]);
+        setClassifiedName(key["name"]);
+        setDescription(key["desc"]);
+        setSnapshotId(key["snapshot_id"]);
+        setCategory((U32)key["category"].asInteger());
+        setContentType((U32)key["content_type"].asInteger());
+        setClassifiedLocation(key["location_text"]);
+        getChild<LLUICtrl>("auto_renew")->setValue(key["auto_renew"]);
+        getChild<LLUICtrl>("price_for_listing")->setValue(key["price_for_listing"].asInteger());
+    }
+}
+
+void LLPanelClassifiedEdit::onOpen(const LLSD& key)
+{
+    mIsNew = key.isUndefined();
+
+    scrollToTop();
+
+    // classified is not created yet
+    bool is_new = isNew() || isNewWithErrors();
+
+    if(is_new)
+    {
+        resetData();
+        resetControls();
+
+        fillIn(key);
+
+        if(isNew())
+        {
+            LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
+        }
+    }
+    else
+    {
+        LLPanelClassifiedInfo::onOpen(key);
+    }
+
+    std::string save_btn_label = is_new ? getString("publish_label") : getString("save_label");
+    getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", save_btn_label);
+
+    enableVerbs(is_new);
+    enableEditing(is_new);
+    showEditing(!is_new);
+    resetDirty();
+    setInfoLoaded(false);
+}
+
+void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType type)
+{
+    if(APT_CLASSIFIED_INFO == type)
+    {
+        LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+        if(c_info && getClassifiedId() == c_info->classified_id)
+        {
+            // see LLPanelClassifiedEdit::sendUpdate() for notes
+            mIsNewWithErrors = false;
+            // for just created classified - panel will probably be closed when we get here.
+            if(!getVisible())
+            {
+                return;
+            }
+
+            enableEditing(true);
+
+            setClassifiedName(c_info->name);
+            setDescription(c_info->description);
+            setSnapshotId(c_info->snapshot_id);
+            setParcelId(c_info->parcel_id);
+            setPosGlobal(c_info->pos_global);
+
+            setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
+            // *HACK see LLPanelClassifiedEdit::sendUpdate()
+            setCategory(c_info->category - 1);
+
+            bool mature = is_cf_mature(c_info->flags);
+            bool auto_renew = is_cf_auto_renew(c_info->flags);
+
+            setContentType(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
+            getChild<LLUICtrl>("auto_renew")->setValue(auto_renew);
+            getChild<LLUICtrl>("price_for_listing")->setValue(c_info->price_for_listing);
+            getChildView("price_for_listing")->setEnabled(isNew());
+
+            resetDirty();
+            setInfoLoaded(true);
+            enableVerbs(false);
+
+            // for just created classified - in case user opened edit panel before processProperties() callback
+            getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", getString("save_label"));
+        }
+    }
+}
+
+BOOL LLPanelClassifiedEdit::isDirty() const
+{
+    if(mIsNew)
+    {
+        return TRUE;
+    }
+
+    BOOL dirty = false;
+
+    dirty |= LLPanelClassifiedInfo::isDirty();
+    dirty |= getChild<LLUICtrl>("classified_snapshot")->isDirty();
+    dirty |= getChild<LLUICtrl>("classified_name")->isDirty();
+    dirty |= getChild<LLUICtrl>("classified_desc")->isDirty();
+    dirty |= getChild<LLUICtrl>("category")->isDirty();
+    dirty |= getChild<LLUICtrl>("content_type")->isDirty();
+    dirty |= getChild<LLUICtrl>("auto_renew")->isDirty();
+    dirty |= getChild<LLUICtrl>("price_for_listing")->isDirty();
+
+    return dirty;
+}
+
+void LLPanelClassifiedEdit::resetDirty()
+{
+    LLPanelClassifiedInfo::resetDirty();
+    getChild<LLUICtrl>("classified_snapshot")->resetDirty();
+    getChild<LLUICtrl>("classified_name")->resetDirty();
+
+    LLTextEditor* desc = getChild<LLTextEditor>("classified_desc");
+    // call blockUndo() to really reset dirty(and make isDirty work as intended)
+    desc->blockUndo();
+    desc->resetDirty();
+
+    getChild<LLUICtrl>("category")->resetDirty();
+    getChild<LLUICtrl>("content_type")->resetDirty();
+    getChild<LLUICtrl>("auto_renew")->resetDirty();
+    getChild<LLUICtrl>("price_for_listing")->resetDirty();
+}
+
+void LLPanelClassifiedEdit::setSaveCallback(const commit_signal_t::slot_type& cb)
+{
+    mSaveButtonClickedSignal.connect(cb);
+}
+
+void LLPanelClassifiedEdit::setCancelCallback(const commit_signal_t::slot_type& cb)
+{
+    getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
+}
+
+void LLPanelClassifiedEdit::resetControls()
+{
+    LLPanelClassifiedInfo::resetControls();
+
+    getChild<LLComboBox>("category")->setCurrentByIndex(0);
+    getChild<LLComboBox>("content_type")->setCurrentByIndex(0);
+    getChild<LLUICtrl>("auto_renew")->setValue(false);
+    if (LLLoginInstance::getInstance()->hasResponse("classified_fee"))
+    {
+        getChild<LLUICtrl>("price_for_listing")->setValue(LLLoginInstance::getInstance()->
+                                                          getResponse("classified_fee").asInteger());
+    }
+    else
+    {
+        getChild<LLUICtrl>("price_for_listing")->setValue(MINIMUM_PRICE_FOR_LISTING);
+    }
+    getChildView("price_for_listing")->setEnabled(TRUE);
+}
+
+bool LLPanelClassifiedEdit::canClose()
+{
+    return mCanClose;
+}
+
+void LLPanelClassifiedEdit::draw()
+{
+    LLPanel::draw();
+
+    // Need to re-stretch on every draw because LLTextureCtrl::onSelectCallback
+    // does not trigger callbacks when user navigates through images.
+    stretchSnapshot();
+}
+
+void LLPanelClassifiedEdit::stretchSnapshot()
+{
+    LLPanelClassifiedInfo::stretchSnapshot();
+
+    getChild<LLUICtrl>("edit_icon")->setShape(mSnapshotCtrl->getRect());
+}
+
+U32 LLPanelClassifiedEdit::getContentType()
+{
+    LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
+    return ct_cb->getCurrentIndex();
+}
+
+void LLPanelClassifiedEdit::setContentType(U32 content_type)
+{
+    LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
+    ct_cb->setCurrentByIndex(content_type);
+    ct_cb->resetDirty();
+}
+
+bool LLPanelClassifiedEdit::getAutoRenew()
+{
+    return getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
+}
+
+void LLPanelClassifiedEdit::sendUpdate()
+{
+    LLAvatarClassifiedInfo c_data;
+
+    if(getClassifiedId().isNull())
+    {
+        setClassifiedId(LLUUID::generateNewID());
+    }
+
+    c_data.agent_id = gAgent.getID();
+    c_data.classified_id = getClassifiedId();
+    // *HACK
+    // Categories on server start with 1 while combo-box index starts with 0
+    c_data.category = getCategory() + 1;
+    c_data.name = getClassifiedName();
+    c_data.description = getDescription();
+    c_data.parcel_id = getParcelId();
+    c_data.snapshot_id = getSnapshotId();
+    c_data.pos_global = getPosGlobal();
+    c_data.flags = getFlags();
+    c_data.price_for_listing = getPriceForListing();
+
+    LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
+
+    if(isNew())
+    {
+        // Lets assume there will be some error.
+        // Successful sendClassifiedInfoUpdate will trigger processProperties and
+        // let us know there was no error.
+        mIsNewWithErrors = true;
+    }
+}
+
+U32 LLPanelClassifiedEdit::getCategory()
+{
+    LLComboBox* cat_cb = getChild<LLComboBox>("category");
+    return cat_cb->getCurrentIndex();
+}
+
+void LLPanelClassifiedEdit::setCategory(U32 category)
+{
+    LLComboBox* cat_cb = getChild<LLComboBox>("category");
+    cat_cb->setCurrentByIndex(category);
+    cat_cb->resetDirty();
+}
+
+U8 LLPanelClassifiedEdit::getFlags()
+{
+    bool auto_renew = getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
+
+    LLComboBox* content_cb = getChild<LLComboBox>("content_type");
+    bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE;
+
+    return pack_classified_flags_request(auto_renew, false, mature, false);
+}
+
+void LLPanelClassifiedEdit::enableVerbs(bool enable)
+{
+    getChildView("save_changes_btn")->setEnabled(enable);
+}
+
+void LLPanelClassifiedEdit::enableEditing(bool enable)
+{
+    getChildView("classified_snapshot")->setEnabled(enable);
+    getChildView("classified_name")->setEnabled(enable);
+    getChildView("classified_desc")->setEnabled(enable);
+    getChildView("set_to_curr_location_btn")->setEnabled(enable);
+    getChildView("category")->setEnabled(enable);
+    getChildView("content_type")->setEnabled(enable);
+    getChildView("price_for_listing")->setEnabled(enable);
+    getChildView("auto_renew")->setEnabled(enable);
+}
+
+void LLPanelClassifiedEdit::showEditing(bool show)
+{
+    getChildView("price_for_listing_label")->setVisible( show);
+    getChildView("price_for_listing")->setVisible( show);
+}
+
+std::string LLPanelClassifiedEdit::makeClassifiedName()
+{
+    std::string name;
+
+    LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+    if(parcel)
+    {
+        name = parcel->getName();
+    }
+
+    if(!name.empty())
+    {
+        return name;
+    }
+
+    LLViewerRegion* region = gAgent.getRegion();
+    if(region)
+    {
+        name = region->getName();
+    }
+
+    return name;
+}
+
+S32 LLPanelClassifiedEdit::getPriceForListing()
+{
+    return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
+}
+
+void LLPanelClassifiedEdit::setPriceForListing(S32 price)
+{
+    getChild<LLUICtrl>("price_for_listing")->setValue(price);
+}
+
+void LLPanelClassifiedEdit::onSetLocationClick()
+{
+    setPosGlobal(gAgent.getPositionGlobal());
+    setParcelId(LLUUID::null);
+
+    std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+    LLViewerRegion* region = gAgent.getRegion();
+    if (region)
+    {
+        region_name = region->getName();
+    }
+
+    setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+
+    // mark classified as dirty
+    setValue(LLSD());
+
+    onChange();
+}
+
+void LLPanelClassifiedEdit::onChange()
+{
+    enableVerbs(isDirty());
+}
+
+void LLPanelClassifiedEdit::onSaveClick()
+{
+    mCanClose = false;
+
+    if(!isValidName())
+    {
+        notifyInvalidName();
+        return;
+    }
+    if(isNew() || isNewWithErrors())
+    {
+        if(gStatusBar->getBalance() < getPriceForListing())
+        {
+            LLNotificationsUtil::add("ClassifiedInsufficientFunds");
+            return;
+        }
+
+        mPublishFloater = LLFloaterReg::findTypedInstance<LLFloaterPublishClassified>(
+            "publish_classified", LLSD());
+
+        if(!mPublishFloater)
+        {
+            mPublishFloater = LLFloaterReg::getTypedInstance<LLFloaterPublishClassified>(
+                "publish_classified", LLSD());
+
+            mPublishFloater->setPublishClickedCallback(boost::bind
+                (&LLPanelClassifiedEdit::onPublishFloaterPublishClicked, this));
+        }
+
+        // set spinner value before it has focus or value wont be set
+        mPublishFloater->setPrice(getPriceForListing());
+        mPublishFloater->openFloater(mPublishFloater->getKey());
+        mPublishFloater->center();
+    }
+    else
+    {
+        doSave();
+    }
+}
+
+void LLPanelClassifiedEdit::doSave()
+{
+    mCanClose = true;
+    sendUpdate();
+    resetDirty();
+
+    mSaveButtonClickedSignal(this, LLSD());
+}
+
+void LLPanelClassifiedEdit::onPublishFloaterPublishClicked()
+{
+    setPriceForListing(mPublishFloater->getPrice());
+
+    doSave();
+}
+
+std::string LLPanelClassifiedEdit::getLocationNotice()
+{
+    static std::string location_notice = getString("location_notice");
+    return location_notice;
+}
+
+bool LLPanelClassifiedEdit::isValidName()
+{
+    std::string name = getClassifiedName();
+    if (name.empty())
+    {
+        return false;
+    }
+    if (!isalnum(name[0]))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+void LLPanelClassifiedEdit::notifyInvalidName()
+{
+    std::string name = getClassifiedName();
+    if (name.empty())
+    {
+        LLNotificationsUtil::add("BlankClassifiedName");
+    }
+    else if (!isalnum(name[0]))
+    {
+        LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
+    }
+}
+
+void LLPanelClassifiedEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
+{
+    ctrl->setVisible(TRUE);
+}
+
+void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
+{
+    ctrl->setVisible(FALSE);
+}
+
+void LLPanelClassifiedEdit::onTextureSelected()
+{
+    setSnapshotId(mSnapshotCtrl->getValue().asUUID());
+    onChange();
+}
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index 88346df6c332825e89cf8c907f48fa5014c47495..e742328df25ebabe47957dd76cb5e5f1b5c104bf 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -1,10 +1,10 @@
 /**
  * @file llpanelclassified.h
- * @brief LLPanelClassifiedInfo class definition
+ * @brief LLPanelClassified class definition
  *
- * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2021, Linden Research, Inc.
+ * Copyright (C) 2010, Linden Research, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,31 +27,34 @@
 // Display of a classified used both for the global view in the
 // Find directory, and also for each individual user's classified in their
 // profile.
+
 #ifndef LL_LLPANELCLASSIFIED_H
 #define LL_LLPANELCLASSIFIED_H
 
 #include "llavatarpropertiesprocessor.h"
-#include "llclassifiedinfo.h"
-#include "llfloater.h"
+#include "llfloaterpublishclassified.h"
 #include "llpanel.h"
 #include "llrect.h"
 
 class LLScrollContainer;
 class LLTextureCtrl;
+class LLUICtrl;
 
 class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
 {
     LOG_CLASS(LLPanelClassifiedInfo);
 public:
 
+    static LLPanelClassifiedInfo* create();
+
     LLPanelClassifiedInfo();
     virtual ~LLPanelClassifiedInfo();
 
-    /*virtual*/ void onOpen(const LLSD& key);
+    /*virtual*/ void onOpen(const LLSD& key) override;
 
-    /*virtual*/ BOOL postBuild();
+    /*virtual*/ BOOL postBuild() override;
 
-    /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
+    /*virtual*/ void processProperties(void* data, EAvatarProcessorType type) override;
 
     void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
 
@@ -112,9 +115,13 @@ class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
             const LLVector3d& global_pos,
             const std::string& sim_name);
 
-    /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+    void setExitCallback(const commit_callback_t& cb);
+
+    void setEditClassifiedCallback(const commit_callback_t& cb);
+
+    /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
 
-    /*virtual*/ void draw();
+    /*virtual*/ void draw() override;
 
 protected:
 
@@ -136,6 +143,7 @@ class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
 
     void onMapClick();
     void onTeleportClick();
+    void onExit();
 
     bool mSnapshotStreched;
     LLRect mSnapshotRect;
@@ -172,4 +180,100 @@ class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
     static panel_list_t sAllPanels;
 };
 
+class LLPanelClassifiedEdit : public LLPanelClassifiedInfo
+{
+    LOG_CLASS(LLPanelClassifiedEdit);
+public:
+
+    static LLPanelClassifiedEdit* create();
+
+    virtual ~LLPanelClassifiedEdit();
+
+    /*virtual*/ BOOL postBuild() override;
+
+    void fillIn(const LLSD& key);
+
+    /*virtual*/ void onOpen(const LLSD& key) override;
+
+    /*virtual*/ void processProperties(void* data, EAvatarProcessorType type) override;
+
+    /*virtual*/ BOOL isDirty() const override;
+
+    /*virtual*/ void resetDirty() override;
+
+    void setSaveCallback(const commit_signal_t::slot_type& cb);
+
+    void setCancelCallback(const commit_signal_t::slot_type& cb);
+
+    /*virtual*/ void resetControls() override;
+
+    bool isNew() { return mIsNew; }
+
+    bool isNewWithErrors() { return mIsNewWithErrors; }
+
+    bool canClose();
+
+    void draw() override;
+
+    void stretchSnapshot();
+
+    U32 getCategory();
+
+    void setCategory(U32 category);
+
+    U32 getContentType();
+
+    void setContentType(U32 content_type);
+
+    bool getAutoRenew();
+
+    S32 getPriceForListing();
+
+protected:
+
+    LLPanelClassifiedEdit();
+
+    void sendUpdate();
+
+    void enableVerbs(bool enable);
+
+    void enableEditing(bool enable);
+
+    void showEditing(bool show);
+
+    std::string makeClassifiedName();
+
+    void setPriceForListing(S32 price);
+
+    U8 getFlags();
+
+    std::string getLocationNotice();
+
+    bool isValidName();
+
+    void notifyInvalidName();
+
+    void onSetLocationClick();
+    void onChange();
+    void onSaveClick();
+
+    void doSave();
+
+    void onPublishFloaterPublishClicked();
+
+    void onTexturePickerMouseEnter(LLUICtrl* ctrl);
+    void onTexturePickerMouseLeave(LLUICtrl* ctrl);
+
+    void onTextureSelected();
+
+private:
+    bool mIsNew;
+    bool mIsNewWithErrors;
+    bool mCanClose;
+
+    LLFloaterPublishClassified* mPublishFloater;
+
+    commit_signal_t mSaveButtonClickedSignal;
+};
+
 #endif // LL_LLPANELCLASSIFIED_H
diff --git a/indra/newview/llpaneleventinfo.cpp b/indra/newview/llpaneleventinfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d9ffc02e42d418449d411fa0f762fc939f710d74
--- /dev/null
+++ b/indra/newview/llpaneleventinfo.cpp
@@ -0,0 +1,158 @@
+/*
+ * @file llpaneleventinfo.cpp
+ * @brief Event info panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpaneleventinfo.h"
+
+#include "llbutton.h"
+#include "lleventflags.h"
+#include "lliconctrl.h"
+#include "llfloaterreg.h"
+#include "llresmgr.h"
+#include "llslurl.h"
+#include "lltrans.h"
+
+#include "llagent.h"
+#include "llfloaterworldmap.h"
+#include "llviewercontrol.h"
+
+static LLPanelInjector<LLPanelEventInfo> t_event_info("panel_event_info");
+
+LLPanelEventInfo::LLPanelEventInfo()
+:   LLPanel()
+,   mEvent()
+,   mEventID(0)
+{
+    mEventNotifierConnection = gEventNotifier.setNewEventCallback(boost::bind(&LLPanelEventInfo::processEventReply, this, _1));
+}
+
+LLPanelEventInfo::~LLPanelEventInfo()
+{
+    if (mEventNotifierConnection.connected())
+    {
+        mEventNotifierConnection.disconnect();
+    }
+}
+
+BOOL LLPanelEventInfo::postBuild()
+{
+    childSetAction("teleport_btn", boost::bind(&LLPanelEventInfo::onBtnTeleport, this));
+    childSetAction("show_on_map_btn", boost::bind(&LLPanelEventInfo::onBtnMap, this));
+    childSetAction("remind_btn", boost::bind(&LLPanelEventInfo::onBtnRemind, this));
+    return TRUE;
+}
+
+void LLPanelEventInfo::onOpen(const LLSD& key)
+{
+    U32 id(key.asInteger());
+    setEventID(id);
+
+    gEventNotifier.add(getEventID());
+}
+
+// *TODO: localize this bitch.
+std::string LLPanelEventInfo::formatFromMinutes(U32 time)
+{
+    U32 hours = time / 60;
+    U32 minutes = time % 60;
+
+    std::ostringstream output;
+    if (hours)
+        output << hours << " " << getString("hours") << " ";
+    if (minutes)
+        output << minutes << " " << getString("minutes");
+    return output.str();
+}
+
+bool LLPanelEventInfo::processEventReply(const LLEventStruct& event)
+{
+    if (event.eventId != getEventID()) return false; // no
+    mEvent = event;
+    getChild<LLUICtrl>("name")->setValue(mEvent.eventName);
+    getChild<LLUICtrl>("desc")->setValue(mEvent.desc);
+    getChild<LLUICtrl>("duration")->setValue(formatFromMinutes(mEvent.duration));
+    getChild<LLUICtrl>("host")->setValue(LLSLURL("agent", LLUUID(mEvent.creator), "inspect").getSLURLString());
+    getChild<LLUICtrl>("time")->setValue(mEvent.eventDateStr);
+    // *TODO: Prettier
+    //std::string time;
+    //LLStringUtil::formatDatetime(time, "%a %d %b %Y %H:%M", "slt", mEvent.eventEpoch);
+    //getChild<LLUICtrl>("time")->setValue(time);
+
+    // *TODO: Add translation strings
+    //getChild<LLUICtrl>("category")->setValue(LLTrans::getString(mEvent.category));
+    getChild<LLUICtrl>("category")->setValue(mEvent.category);
+    getChild<LLUICtrl>("cover")->setValue(mEvent.cover
+                                          ? LLResMgr::getInstance()->getMonetaryString(mEvent.amount)
+                                          : getString("free"));
+    bool mature = (mEvent.flags & EVENT_FLAG_MATURE);
+    getChild<LLUICtrl>("content_type")->setValue(getString(mature ? "type_mature" : "type_pg"));
+    getChild<LLIconCtrl>("content_type_moderate")->setVisible(mature);
+    getChild<LLIconCtrl>("content_type_general")->setVisible(!mature);
+    getChild<LLUICtrl>("location")->setValue(LLSLURL(mEvent.simName, mEvent.globalPos).getSLURLString());
+    getChild<LLButton>("remind_btn")->setLabel(getString(gEventNotifier.hasNotification(mEvent.eventId)
+                                                         ? "no_reminder"
+                                                         : "reminder"));
+    return true;
+}
+
+void LLPanelEventInfo::onBtnTeleport()
+{
+    if (!mEvent.globalPos.isExactlyZero())
+    {
+        gAgent.teleportViaLocation(mEvent.globalPos);
+        LLFloaterWorldMap* worldmap = LLFloaterWorldMap::getInstance();
+        if (worldmap)
+            worldmap->trackLocation(mEvent.globalPos);
+    }
+}
+
+void LLPanelEventInfo::onBtnMap()
+{
+    LLFloaterWorldMap* worldmap = LLFloaterWorldMap::getInstance();
+    if (!mEvent.globalPos.isExactlyZero() && worldmap)
+    {
+        worldmap->trackLocation(mEvent.globalPos);
+        LLFloaterReg::showInstance("world_map", "center");
+    }
+}
+
+void LLPanelEventInfo::onBtnRemind()
+{
+    if (gEventNotifier.hasNotification(mEvent.eventId))
+    {
+        gEventNotifier.remove(mEvent.eventId);
+        getChild<LLButton>("remind_btn")->setLabel(getString("reminder"));
+    }
+    else
+    {
+        gEventNotifier.add(mEvent.eventId);
+        getChild<LLButton>("remind_btn")->setLabel(getString("no_reminder"));
+    }
+}
diff --git a/indra/newview/llpaneleventinfo.h b/indra/newview/llpaneleventinfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..3852dba91ed9248bead9ce789839f1bca11d9860
--- /dev/null
+++ b/indra/newview/llpaneleventinfo.h
@@ -0,0 +1,59 @@
+/*
+ * @file llpaneleventinfo.cpp
+ * @brief Event info panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELEVENTINFO_H
+#define LL_PANELEVENTINFO_H
+
+#include "llpanel.h"
+#include "lleventnotifier.h"
+
+class LLPanelEventInfo : public LLPanel
+{
+public:
+    LLPanelEventInfo();
+    /*virtual*/ BOOL postBuild() override;
+    /*virtual*/ void onOpen(const LLSD& key) override;
+
+private:
+    ~LLPanelEventInfo();
+    bool processEventReply(const LLEventStruct& event);
+    std::string formatFromMinutes(U32 time);
+    void setEventID(U32 id) { mEventID = id; }
+    U32 getEventID() const { return mEventID; }
+    void onBtnTeleport();
+    void onBtnMap();
+    void onBtnRemind();
+
+    LLEventStruct mEvent;
+    U32 mEventID;
+    boost::signals2::connection mEventNotifierConnection;
+};
+
+#endif // LL_PANELEVENTINFO_H
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index f05f92706713dd734736df804a5c119efef7ae9a..95bc7896f44f7b90d6d837d9657c62b5af649d15 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -1104,11 +1104,7 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
     data.snapshot_id = parcel_data.snapshot_id;
     data.parcel_id = parcel_data.parcel_id;
 
-    LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
-    if (profile_floater)
-    {
-        profile_floater->createPick(data);
-    }
+    LLAvatarActions::createPick(data);
 }
 
 void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..113f9b0b9e418015289578820242b9e114ca8c76
--- /dev/null
+++ b/indra/newview/llpanelpick.cpp
@@ -0,0 +1,612 @@
+/**
+ * @file llpanelpick.cpp
+ * @brief LLPanelPick class implementation
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+// Display of a "Top Pick" used both for the global top picks in the
+// Find directory, and also for each individual user's picks in their
+// profile.
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelpick.h"
+
+#include "message.h"
+
+#include "llparcel.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "lliconctrl.h"
+#include "lllineeditor.h"
+#include "llpanel.h"
+#include "llscrollcontainer.h"
+#include "lltexteditor.h"
+
+#include "llagent.h"
+#include "llagentpicksinfo.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llfloaterworldmap.h"
+#include "lltexturectrl.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+static const std::string XML_PANEL_EDIT_PICK("panel_edit_pick.xml");
+static const std::string XML_PANEL_PICK_INFO("panel_pick_info.xml");
+
+static const std::string XML_NAME("pick_name");
+static const std::string XML_DESC("pick_desc");
+static const std::string XML_SNAPSHOT("pick_snapshot");
+static const std::string XML_LOCATION("pick_location");
+
+static const std::string XML_BTN_ON_TXTR("edit_icon");
+static const std::string XML_BTN_SAVE("save_changes_btn");
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+//static
+LLPanelPickInfo* LLPanelPickInfo::create()
+{
+    LLPanelPickInfo* panel = new LLPanelPickInfo();
+    panel->buildFromFile(XML_PANEL_PICK_INFO);
+    return panel;
+}
+
+LLPanelPickInfo::LLPanelPickInfo()
+ : LLPanel()
+ , LLAvatarPropertiesObserver()
+ , LLRemoteParcelInfoObserver()
+ , mScrollingPanelMinHeight(0)
+ , mScrollingPanelWidth(0)
+ , mScrollContainer(nullptr)
+ , mScrollingPanel(nullptr)
+ , mSnapshotCtrl(nullptr)
+ , mAvatarId(LLUUID::null)
+ , mParcelId(LLUUID::null)
+ , mPickId(LLUUID::null)
+ , mRequestedId(LLUUID::null)
+{
+}
+
+LLPanelPickInfo::~LLPanelPickInfo()
+{
+    LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLPanelPickInfo::getAvatarId(), this);
+
+    if (mParcelId.notNull())
+    {
+        LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+    }
+}
+
+void LLPanelPickInfo::onOpen(const LLSD& key)
+{
+    LLUUID avatar_id = key["avatar_id"];
+    if(avatar_id.isNull())
+    {
+        return;
+    }
+
+    if(getAvatarId().notNull())
+    {
+        LLAvatarPropertiesProcessor::getInstance()->removeObserver(
+            getAvatarId(), this);
+    }
+
+    setAvatarId(avatar_id);
+
+    resetData();
+    resetControls();
+
+    setPickId(key["pick_id"]);
+    setPickName(key["pick_name"]);
+    setPickDesc(key["pick_desc"]);
+    setSnapshotId(key["snapshot_id"]);
+
+    LLAvatarPropertiesProcessor::getInstance()->addObserver(
+        getAvatarId(), this);
+    LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(
+        getAvatarId(), getPickId());
+}
+
+BOOL LLPanelPickInfo::postBuild()
+{
+    mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT);
+
+    childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this));
+    childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this));
+    childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this));
+
+    mScrollingPanel = getChild<LLPanel>("scroll_content_panel");
+    mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
+
+    mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
+    mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
+
+    LLTextEditor* text_desc = getChild<LLTextEditor>(XML_DESC);
+    text_desc->setContentTrusted(false);
+
+    return TRUE;
+}
+
+void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+    LLPanel::reshape(width, height, called_from_parent);
+
+    if (!mScrollContainer || !mScrollingPanel)
+        return;
+
+    static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+    S32 scroll_height = mScrollContainer->getRect().getHeight();
+    if (mScrollingPanelMinHeight >= scroll_height)
+    {
+        mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight);
+    }
+    else
+    {
+        mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height);
+    }
+}
+
+void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type)
+{
+    if(APT_PICK_INFO != type)
+    {
+        return;
+    }
+    LLPickData* pick_info = static_cast<LLPickData*>(data);
+    if(!pick_info
+        || pick_info->creator_id != getAvatarId()
+        || pick_info->pick_id != getPickId())
+    {
+        return;
+    }
+
+    mParcelId = pick_info->parcel_id;
+    setSnapshotId(pick_info->snapshot_id);
+    setPickName(pick_info->name);
+    setPickDesc(pick_info->desc);
+    setPosGlobal(pick_info->pos_global);
+
+    // Send remote parcel info request to get parcel name and sim (region) name.
+    sendParcelInfoRequest();
+
+    // *NOTE dzaporozhan
+    // We want to keep listening to APT_PICK_INFO because user may
+    // edit the Pick and we have to update Pick info panel.
+    // revomeObserver is called from onClickBack
+}
+
+void LLPanelPickInfo::sendParcelInfoRequest()
+{
+    if (mParcelId != mRequestedId)
+    {
+        LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
+        LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
+
+        mRequestedId = mParcelId;
+    }
+}
+
+void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb)
+{
+    getChild<LLButton>("back_btn")->setClickedCallback(cb);
+}
+
+void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data)
+{
+    setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name,
+        parcel_data.sim_name, getPosGlobal()));
+
+    // We have received parcel info for the requested ID so clear it now.
+    mRequestedId.setNull();
+
+    if (mParcelId.notNull())
+    {
+        LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+    }
+}
+
+void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb)
+{
+    getChild<LLButton>("edit_btn")->setClickedCallback(cb);
+}
+
+// PROTECTED AREA
+
+void LLPanelPickInfo::resetControls()
+{
+    if(getAvatarId() == gAgent.getID())
+    {
+        getChildView("edit_btn")->setEnabled(TRUE);
+        getChildView("edit_btn")->setVisible( TRUE);
+    }
+    else
+    {
+        getChildView("edit_btn")->setEnabled(FALSE);
+        getChildView("edit_btn")->setVisible( FALSE);
+    }
+}
+
+void LLPanelPickInfo::resetData()
+{
+    setPickName(LLStringUtil::null);
+    setPickDesc(LLStringUtil::null);
+    setPickLocation(LLStringUtil::null);
+    setPickId(LLUUID::null);
+    setSnapshotId(LLUUID::null);
+    mPosGlobal.clearVec();
+    mParcelId.setNull();
+    mRequestedId.setNull();
+}
+
+// static
+std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
+{
+    std::string location_text;
+    location_text.append(owner_name);
+    if (!original_name.empty())
+    {
+        if (!location_text.empty()) location_text.append(", ");
+        location_text.append(original_name);
+
+    }
+    if (!sim_name.empty())
+    {
+        if (!location_text.empty()) location_text.append(", ");
+        location_text.append(sim_name);
+    }
+
+    if (!location_text.empty()) location_text.append(" ");
+
+    if (!pos_global.isNull())
+    {
+        S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+        S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+        S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
+        location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+    }
+    return location_text;
+}
+
+void LLPanelPickInfo::setSnapshotId(const LLUUID& id)
+{
+    mSnapshotCtrl->setImageAssetID(id);
+    mSnapshotCtrl->setValid(TRUE);
+}
+
+void LLPanelPickInfo::setPickName(const std::string& name)
+{
+    getChild<LLUICtrl>(XML_NAME)->setValue(name);
+}
+
+void LLPanelPickInfo::setPickDesc(const std::string& desc)
+{
+    getChild<LLUICtrl>(XML_DESC)->setValue(desc);
+}
+
+void LLPanelPickInfo::setPickLocation(const std::string& location)
+{
+    getChild<LLUICtrl>(XML_LOCATION)->setValue(location);
+}
+
+void LLPanelPickInfo::onClickMap()
+{
+    LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+    LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelPickInfo::onClickTeleport()
+{
+    if (!getPosGlobal().isExactlyZero())
+    {
+        gAgent.teleportViaLocation(getPosGlobal());
+        LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+    }
+}
+
+void LLPanelPickInfo::onClickBack()
+{
+    LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+//static
+LLPanelPickEdit* LLPanelPickEdit::create()
+{
+    LLPanelPickEdit* panel = new LLPanelPickEdit();
+    panel->buildFromFile(XML_PANEL_EDIT_PICK);
+    return panel;
+}
+
+LLPanelPickEdit::LLPanelPickEdit()
+ : LLPanelPickInfo()
+ , mLocationChanged(false)
+ , mNeedData(true)
+ , mNewPick(false)
+ , text_icon(nullptr)
+{
+}
+
+void LLPanelPickEdit::onOpen(const LLSD& key)
+{
+    LLUUID pick_id = key["pick_id"];
+    mNeedData = true;
+
+    // creating new Pick
+    if(pick_id.isNull())
+    {
+        mNewPick = true;
+
+        setAvatarId(gAgent.getID());
+
+        resetData();
+        resetControls();
+
+        setPosGlobal(gAgent.getPositionGlobal());
+
+        LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
+        std::string pick_name, pick_desc, region_name;
+
+        LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+        if(parcel)
+        {
+            parcel_id = parcel->getID();
+            pick_name = parcel->getName();
+            pick_desc = parcel->getDesc();
+            snapshot_id = parcel->getSnapshotID();
+        }
+
+        LLViewerRegion* region = gAgent.getRegion();
+        if(region)
+        {
+            region_name = region->getName();
+        }
+
+        setParcelID(parcel_id);
+        getChild<LLUICtrl>("pick_name")->setValue(pick_name.empty() ? region_name : pick_name);
+        getChild<LLUICtrl>("pick_desc")->setValue(pick_desc);
+        setSnapshotId(snapshot_id);
+        setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
+
+        enableSaveButton(true);
+    }
+    // editing existing pick
+    else
+    {
+        mNewPick = false;
+        LLPanelPickInfo::onOpen(key);
+
+        enableSaveButton(false);
+    }
+
+    resetDirty();
+}
+
+void LLPanelPickEdit::setPickData(const LLPickData* pick_data)
+{
+    if(!pick_data)
+    {
+        return;
+    }
+
+    mNeedData = false;
+
+    setParcelID(pick_data->parcel_id);
+    getChild<LLUICtrl>("pick_name")->setValue(pick_data->name);
+    getChild<LLUICtrl>("pick_desc")->setValue(pick_data->desc);
+    setSnapshotId(pick_data->snapshot_id);
+    setPosGlobal(pick_data->pos_global);
+    setPickLocation(createLocationText(LLStringUtil::null, pick_data->name,
+            pick_data->sim_name, pick_data->pos_global));
+}
+
+BOOL LLPanelPickEdit::postBuild()
+{
+    LLPanelPickInfo::postBuild();
+
+    mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this));
+
+    LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
+    line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), nullptr);
+
+    LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
+    text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1));
+
+    childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this));
+    childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this));
+
+    initTexturePickerMouseEvents();
+
+    return TRUE;
+}
+
+void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb)
+{
+    getChild<LLButton>("save_changes_btn")->setClickedCallback(cb);
+}
+
+void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb)
+{
+    getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
+}
+
+void LLPanelPickEdit::resetDirty()
+{
+    LLPanelPickInfo::resetDirty();
+
+    getChild<LLLineEditor>("pick_name")->resetDirty();
+    getChild<LLTextEditor>("pick_desc")->resetDirty();
+    mSnapshotCtrl->resetDirty();
+    mLocationChanged = false;
+}
+
+BOOL LLPanelPickEdit::isDirty() const
+{
+    if( mNewPick
+        || LLPanelPickInfo::isDirty()
+        || mLocationChanged
+        || mSnapshotCtrl->isDirty()
+        || getChild<LLLineEditor>("pick_name")->isDirty()
+        || getChild<LLTextEditor>("pick_desc")->isDirty())
+    {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+void LLPanelPickEdit::sendUpdate()
+{
+    LLPickData pick_data;
+
+    // If we don't have a pick id yet, we'll need to generate one,
+    // otherwise we'll keep overwriting pick_id 00000 in the database.
+    if (getPickId().isNull())
+    {
+        getPickId().generate();
+    }
+
+    pick_data.agent_id = gAgent.getID();
+    pick_data.session_id = gAgent.getSessionID();
+    pick_data.pick_id = getPickId();
+    pick_data.creator_id = gAgent.getID();;
+
+    //legacy var  need to be deleted
+    pick_data.top_pick = FALSE;
+    pick_data.parcel_id = mParcelId;
+    pick_data.name = getChild<LLUICtrl>(XML_NAME)->getValue().asString();
+    pick_data.desc = getChild<LLUICtrl>(XML_DESC)->getValue().asString();
+    pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
+    pick_data.pos_global = getPosGlobal();
+    pick_data.sort_order = 0;
+    pick_data.enabled = TRUE;
+
+    LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data);
+
+    if(mNewPick)
+    {
+        // Assume a successful create pick operation, make new number of picks
+        // available immediately. Actual number of picks will be requested in
+        // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
+        LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
+    }
+}
+
+void LLPanelPickEdit::onSnapshotChanged()
+{
+    enableSaveButton(true);
+}
+
+void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl)
+{
+    enableSaveButton(isDirty());
+}
+
+void LLPanelPickEdit::resetData()
+{
+    LLPanelPickInfo::resetData();
+    mLocationChanged = false;
+}
+
+void LLPanelPickEdit::enableSaveButton(bool enable)
+{
+    getChildView(XML_BTN_SAVE)->setEnabled(enable);
+}
+
+void LLPanelPickEdit::onClickSetLocation()
+{
+    // Save location for later use.
+    setPosGlobal(gAgent.getPositionGlobal());
+
+    std::string parcel_name, region_name;
+
+    LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+    if (parcel)
+    {
+        mParcelId = parcel->getID();
+        parcel_name = parcel->getName();
+    }
+
+    LLViewerRegion* region = gAgent.getRegion();
+    if(region)
+    {
+        region_name = region->getName();
+    }
+
+    setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
+
+    mLocationChanged = true;
+    enableSaveButton(TRUE);
+}
+
+void LLPanelPickEdit::onClickSave()
+{
+    sendUpdate();
+
+    mLocationChanged = false;
+
+    LLSD params;
+    params["action"] = "save_new_pick";
+    notifyParent(params);
+}
+
+std::string LLPanelPickEdit::getLocationNotice()
+{
+    static std::string notice = getString("location_notice");
+    return notice;
+}
+
+void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type)
+{
+    if(mNeedData)
+    {
+        LLPanelPickInfo::processProperties(data, type);
+    }
+}
+
+// PRIVATE AREA
+
+void LLPanelPickEdit::initTexturePickerMouseEvents()
+{
+    text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR);
+    mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1));
+    mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1));
+
+    text_icon->setVisible(FALSE);
+}
+
+void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
+{
+        text_icon->setVisible(TRUE);
+}
+
+void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
+{
+    text_icon->setVisible(FALSE);
+}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
new file mode 100644
index 0000000000000000000000000000000000000000..21f2b7d702447d5bae55143fe0173c59334b08e8
--- /dev/null
+++ b/indra/newview/llpanelpick.h
@@ -0,0 +1,255 @@
+/**
+ * @file llpanelpick.h
+ * @brief LLPanelPick class definition
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+// Display of a "Top Pick" used both for the global top picks in the
+// Find directory, and also for each individual user's picks in their
+// profile.
+
+#ifndef LL_LLPANELPICK_H
+#define LL_LLPANELPICK_H
+
+#include "llpanel.h"
+#include "llremoteparcelrequest.h"
+#include "llavatarpropertiesprocessor.h"
+
+class LLIconCtrl;
+class LLTextureCtrl;
+class LLScrollContainer;
+class LLMessageSystem;
+class LLAvatarPropertiesObserver;
+
+/**
+ * Panel for displaying Pick Information - snapshot, name, description, etc.
+ */
+class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver
+{
+    LOG_CLASS(LLPanelPickInfo);
+public:
+
+    // Creates new panel
+    static LLPanelPickInfo* create();
+
+    virtual ~LLPanelPickInfo();
+
+    /**
+     * Initializes panel properties
+     *
+     * By default Pick will be created for current Agent location.
+     * Use setPickData to change Pick properties.
+     */
+    /*virtual*/ void onOpen(const LLSD& key) override;
+
+    /*virtual*/ BOOL postBuild() override;
+
+    /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
+
+    /*virtual*/ void processProperties(void* data, EAvatarProcessorType type) override;
+
+    /**
+     * Sends remote parcel info request to resolve parcel name from its ID.
+     */
+    void sendParcelInfoRequest();
+
+    /**
+     * Sets "Back" button click callback
+     */
+    virtual void setExitCallback(const commit_callback_t& cb);
+
+    /**
+     * Sets "Edit" button click callback
+     */
+    virtual void setEditPickCallback(const commit_callback_t& cb);
+
+    //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
+    /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data) override;
+    /*virtual*/ void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; }
+    /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) override {};
+
+protected:
+
+    LLPanelPickInfo();
+
+    /**
+     * Resets Pick information
+     */
+    virtual void resetData();
+
+    /**
+     * Resets UI controls (visibility, values)
+     */
+    virtual void resetControls();
+
+    /**
+    * "Location text" is actually the owner name, the original
+    * name that owner gave the parcel, and the location.
+    */
+    static std::string createLocationText(
+        const std::string& owner_name,
+        const std::string& original_name,
+        const std::string& sim_name,
+        const LLVector3d& pos_global);
+
+    virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
+    virtual LLUUID& getAvatarId() { return mAvatarId; }
+
+    /**
+     * Sets snapshot id.
+     *
+     * Will mark snapshot control as valid if id is not null.
+     * Will mark snapshot control as invalid if id is null. If null id is a valid value,
+     * you have to manually mark snapshot is valid.
+     */
+    virtual void setSnapshotId(const LLUUID& id);
+
+    virtual void setPickId(const LLUUID& id) { mPickId = id; }
+    virtual LLUUID& getPickId() { return mPickId; }
+
+    virtual void setPickName(const std::string& name);
+
+    virtual void setPickDesc(const std::string& desc);
+
+    virtual void setPickLocation(const std::string& location);
+
+    virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+    virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+    /**
+     * Callback for "Map" button, opens Map
+     */
+    void onClickMap();
+
+    /**
+     * Callback for "Teleport" button, teleports user to Pick location.
+     */
+    void onClickTeleport();
+
+    void onClickBack();
+
+    S32                     mScrollingPanelMinHeight;
+    S32                     mScrollingPanelWidth;
+    LLScrollContainer*      mScrollContainer;
+    LLPanel*                mScrollingPanel;
+    LLTextureCtrl*          mSnapshotCtrl;
+
+    LLUUID mAvatarId;
+    LLVector3d mPosGlobal;
+    LLUUID mParcelId;
+    LLUUID mPickId;
+    LLUUID mRequestedId;
+};
+
+/**
+ * Panel for creating/editing Pick.
+ */
+class LLPanelPickEdit final : public LLPanelPickInfo
+{
+    LOG_CLASS(LLPanelPickEdit);
+public:
+
+    /**
+     * Creates new panel
+     */
+    static LLPanelPickEdit* create();
+
+    ~LLPanelPickEdit() = default;
+    void onOpen(const LLSD& key) override;
+    virtual void setPickData(const LLPickData* pick_data);
+    BOOL postBuild() override;
+
+    /**
+     * Sets "Save" button click callback
+     */
+    virtual void setSaveCallback(const commit_callback_t& cb);
+
+    /**
+     * Sets "Cancel" button click callback
+     */
+    virtual void setCancelCallback(const commit_callback_t& cb);
+
+    /**
+     * Resets panel and all cantrols to unedited state
+     */
+    void resetDirty() override;
+
+    /**
+     * Returns true if any of Pick properties was changed by user.
+     */
+    BOOL isDirty() const override;
+
+    void processProperties(void* data, EAvatarProcessorType type) override;
+
+    /**
+    * Sends Pick properties to server.
+    */
+    void sendUpdate();
+
+protected:
+
+    LLPanelPickEdit();
+
+    /**
+     * Called when snapshot image changes.
+     */
+    void onSnapshotChanged();
+
+    /**
+     * Callback for Pick snapshot, name and description changed event.
+     */
+    void onPickChanged(LLUICtrl* ctrl);
+
+    /*virtual*/ void resetData() override;
+
+    /**
+     * Enables/disables "Save" button
+     */
+    void enableSaveButton(bool enable);
+
+    /**
+     * Callback for "Set Location" button click
+     */
+    void onClickSetLocation();
+
+    /**
+     * Callback for "Save" button click
+     */
+    void onClickSave();
+
+    std::string getLocationNotice();
+
+    bool mLocationChanged;
+    bool mNeedData;
+    bool mNewPick;
+
+private:
+
+    void initTexturePickerMouseEvents();
+        void onTexturePickerMouseEnter(LLUICtrl* ctrl);
+    void onTexturePickerMouseLeave(LLUICtrl* ctrl);
+
+    LLIconCtrl* text_icon;
+};
+
+#endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 3f12deb36ad99bea57d9f8d99597b50bb8f13e86..f1445ad4386d74b7afca8b458e140ca59eadd160 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -321,11 +321,7 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global)
     data.snapshot_id = mSnapshotCtrl->getImageAssetID();
     data.parcel_id = mParcelID;
 
-    LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
-    if (profile_floater)
-    {
-        profile_floater->createPick(data);
-    }
+    LLAvatarActions::createPick(data);
 }
 
 // static
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 68fbfa3fb0a4f3ae7148f2d0a8795535806acb9f..f6d19dfe9bd2d321a48cd60238da5864d318bb3b 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -62,8 +62,7 @@
 #include "llcommandhandler.h"
 #include "llfloaterprofiletexture.h"
 #include "llfloaterreg.h"
-#include "llfloaterblocked.h"
-#include "llfloaterreporter.h"
+#include "lltexturectrl.h"
 #include "llfilepicker.h"
 #include "llfirstuse.h"
 #include "llgroupactions.h"
@@ -104,167 +103,14 @@ static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage";
 
 //////////////////////////////////////////////////////////////////////////
 
-LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle)
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-    LLCore::HttpHeaders::ptr_t httpHeaders;
-
-    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-    httpOpts->setFollowRedirects(true);
-
-    LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
-
-    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
-    if (!status)
-    {
-        // todo: notification?
-        LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
-        return LLUUID::null;
-    }
-    if (!result.has("uploader"))
-    {
-        // todo: notification?
-        LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
-        return LLUUID::null;
-    }
-    std::string uploader_cap = result["uploader"].asString();
-    if (uploader_cap.empty())
-    {
-        LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
-        return LLUUID::null;
-    }
-
-    // Upload the image
-    LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest);
-    LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders);
-    LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions);
-    S64 length;
-
-    {
-        llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
-        if (!instream.is_open())
-        {
-            LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
-            return LLUUID::null;
-        }
-        length = instream.tellg();
-    }
-
-    uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
-    uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
-    uploaderhttpOpts->setFollowRedirects(true);
-
-    result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
-
-    httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
-    LL_DEBUGS("AvatarProperties") << result << LL_ENDL;
-
-    if (!status)
-    {
-        LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL;
-        return LLUUID::null;
-    }
-
-    if (result["state"].asString() != "complete")
-    {
-        if (result.has("message"))
-        {
-            LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
-        }
-        else
-        {
-            LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL;
-        }
-        return LLUUID::null;
-    }
-
-    return result["new_asset"].asUUID();
-}
-
-enum EProfileImageType
-{
-    PROFILE_IMAGE_SL,
-    PROFILE_IMAGE_FL,
-};
-
-void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle<LLPanel> *handle)
-{
-    LLSD data;
-    switch (type)
-    {
-    case PROFILE_IMAGE_SL:
-        data["profile-image-asset"] = "sl_image_id";
-        break;
-    case PROFILE_IMAGE_FL:
-        data["profile-image-asset"] = "fl_image_id";
-        break;
-    }
-
-    LLUUID result = post_profile_image(cap_url, data, path_to_image, handle);
-
-    // reset loading indicator
-    if (!handle->isDead())
-    {
-        switch (type)
-        {
-        case PROFILE_IMAGE_SL:
-            {
-                LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get());
-                if (result.notNull())
-                {
-                    panel->setProfileImageUploaded(result);
-                }
-                else
-                {
-                    // failure, just stop progress indicator
-                    panel->setProfileImageUploading(false);
-                }
-                break;
-            }
-        case PROFILE_IMAGE_FL:
-            {
-                LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(handle->get());
-                if (result.notNull())
-                {
-                    panel->setProfileImageUploaded(result);
-                }
-                else
-                {
-                    // failure, just stop progress indicator
-                    panel->setProfileImageUploading(false);
-                }
-                break;
-            }
-        }
-    }
-
-    if (type == PROFILE_IMAGE_SL && result.notNull())
-    {
-        LLAvatarIconIDCache::getInstance()->add(gAgentID, result);
-        // Should trigger callbacks in icon controls
-        LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID);
-    }
-
-    // Cleanup
-    LLFile::remove(path_to_image);
-    delete handle;
-}
-
 //////////////////////////////////////////////////////////////////////////
-// LLProfileHandler
+// LLWebProfileHandler
 
-class LLProfileHandler : public LLCommandHandler
+class LLWebProfileHandler : public LLCommandHandler
 {
 public:
     // requires trusted browser to trigger
-    LLProfileHandler() : LLCommandHandler("profile", UNTRUSTED_THROTTLE) { }
+    LLWebProfileHandler() : LLCommandHandler("profile", UNTRUSTED_THROTTLE) { }
 
     bool handle(const LLSD& params,
                 const LLSD& query_map,
@@ -280,6 +126,8 @@ class LLProfileHandler : public LLCommandHandler
         return true;
     }
 };
+LLWebProfileHandler gWebProfileHandler;
+#if 0 // ALCHMERGE
 LLProfileHandler gProfileHandler;
 
 
@@ -324,7 +172,7 @@ class LLAgentHandler : public LLCommandHandler
     {
         if (params.size() < 2) return false;
         LLUUID avatar_id;
-        if (!avatar_id.set(params[0].asString(), FALSE))
+        if (!avatar_id.set(params[0], FALSE))
         {
             return false;
         }
@@ -403,8 +251,7 @@ class LLAgentHandler : public LLCommandHandler
                 const std::string object_name = LLURI::unescape(params[2].asString());
                 LLMute mute(avatar_id, object_name, LLMute::OBJECT);
                 LLMuteList::getInstance()->add(mute);
-                LLFloaterBlocked::showMuteAndSelect(mute.mID);
-                //LLPanelBlockedList::showPanelAndSelect(mute.mID);
+                LLPanelBlockedList::showPanelAndSelect(mute.mID);
             }
             return true;
         }
@@ -439,7 +286,7 @@ class LLAgentHandler : public LLCommandHandler
     }
 };
 LLAgentHandler gAgentHandler;
-
+#endif
 
 ///----------------------------------------------------------------------------
 /// LLFloaterProfilePermissions
@@ -1268,93 +1115,12 @@ void LLPanelProfileSecondLife::setLoaded()
     }
 }
 
-
-class LLProfileImagePicker : public LLFilePickerThread
-{
-public:
-    LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle);
-    ~LLProfileImagePicker();
-    void notify(const std::vector<std::string>& filenames) override;
-
-private:
-    LLHandle<LLPanel> *mHandle;
-    EProfileImageType mType;
-};
-
-LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle)
-    : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE),
-    mHandle(handle),
-    mType(type)
-{
-}
-
-LLProfileImagePicker::~LLProfileImagePicker()
-{
-    delete mHandle;
-}
-
-void LLProfileImagePicker::notify(const std::vector<std::string>& filenames)
-{
-    if (mHandle->isDead())
-    {
-        return;
-    }
-    if (filenames.empty())
-    {
-        return;
-    }
-    std::string file_path = filenames[0];
-    if (file_path.empty())
-    {
-        return;
-    }
-
-    // generate a temp texture file for coroutine
-    std::string temp_file = gDirUtilp->getTempFilename();
-    U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path));
-    const S32 MAX_DIM = 256;
-    if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM))
-    {
-        //todo: image not supported notification
-        LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL;
-        return;
-    }
-
-    std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
-    if (cap_url.empty())
-    {
-        LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL;
-        return;
-    }
-
-    switch (mType)
-    {
-    case PROFILE_IMAGE_SL:
-        {
-            LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get());
-            panel->setProfileImageUploading(true);
-        }
-        break;
-    case PROFILE_IMAGE_FL:
-        {
-            LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(mHandle->get());
-            panel->setProfileImageUploading(true);
-        }
-        break;
-    }
-
-    LLCoros::instance().launch("postAgentUserImageCoro",
-        boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle));
-
-    mHandle = nullptr; // transferred to post_profile_image_coro
-}
-
 void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)
 {
     const std::string item_name = userdata.asString();
     const LLUUID agent_id = getAvatarId();
     // todo: consider moving this into LLAvatarActions::onCommit(name, id)
-    // and making all other flaoters, like people menu do the same
+    // and making all other floaters, like people menu, do the same
     if (item_name == "im")
     {
         LLAvatarActions::startIM(agent_id);
@@ -1457,7 +1223,8 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)
     }
     else if (item_name == "upload_photo")
     {
-        (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(LLPanel::getHandle())))->getFile();
+        (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(LLPanel::getHandle()),
+                                  [this] (LLUUID const& id) { setProfileImageUploaded(id); }))->getFile();
 
         LLFloater* floaterp = mFloaterTexturePickerHandle.get();
         if (floaterp)
@@ -2007,7 +1774,8 @@ void LLPanelProfileFirstLife::commitUnsavedChanges()
 
 void LLPanelProfileFirstLife::onUploadPhoto()
 {
-    (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(LLPanel::getHandle())))->getFile();
+    (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(LLPanel::getHandle()),
+                              [this](LLUUID const& id) { setProfileImageUploaded(id); }))->getFile();
 
     LLFloater* floaterp = mFloaterTexturePickerHandle.get();
     if (floaterp)
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index a2f0fbbfe1df0effbbf38dd591f98dbfa3f1b0af..1f7435eaa821b2eea73aab714b321e59fd311eca 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -33,6 +33,7 @@
 #include "llpanel.h"
 #include "llpanelavatar.h"
 #include "llmediactrl.h"
+#include "llprofileimagepicker.h"
 #include "llvoiceclient.h"
 
 // class LLPanelProfileClassifieds;
diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp
index 23266a2279f78b2e8b5f7c5302bcb51e14487885..e2768ff807491c6821318d3c83496feca725aa91 100644
--- a/indra/newview/llpanelprofileclassifieds.cpp
+++ b/indra/newview/llpanelprofileclassifieds.cpp
@@ -32,13 +32,14 @@
 #include "llavataractions.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llclassifiedflags.h"
+#include "llclassifiedinfo.h"
 #include "llcombobox.h"
 #include "llcommandhandler.h" // for classified HTML detail page click tracking
 #include "llcorehttputil.h"
 #include "lldispatcher.h"
 #include "llfloaterclassified.h"
 #include "llfloaterreg.h"
-#include "llfloatersidepanelcontainer.h"
+#include "llfloaterpublishclassified.h"
 #include "llfloaterworldmap.h"
 #include "lliconctrl.h"
 #include "lllineeditor.h"
@@ -46,7 +47,6 @@
 #include "llnotificationsutil.h"
 #include "llpanelavatar.h"
 #include "llparcel.h"
-#include "llregistry.h"
 #include "llscrollcontainer.h"
 #include "llstartup.h"
 #include "llstatusbar.h"
@@ -57,8 +57,6 @@
 #include "llviewergenericmessage.h" // send_generic_message
 #include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
-#include "llviewertexture.h"
-#include "llviewertexture.h"
 #include "rlvactions.h"
 #include "rlvhandler.h"
 
@@ -66,7 +64,6 @@
 //*TODO: verify this limit
 const S32 MAX_AVATAR_CLASSIFIEDS = 100;
 
-const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
 const S32 DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT = 530;
 
 //static
@@ -137,7 +134,7 @@ class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesOb
 
         // get the ID for the classified
         LLUUID classified_id;
-        if (!classified_id.set(params[0].asString(), FALSE))
+        if (!classified_id.set(params[0].asStringRef(), FALSE))
         {
             return false;
         }
@@ -981,12 +978,12 @@ void LLPanelProfileClassified::onSaveClick()
             return;
         }
 
-        mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
+        mPublishFloater = LLFloaterReg::findTypedInstance<LLFloaterPublishClassified>(
             "publish_classified", LLSD());
 
         if(!mPublishFloater)
         {
-            mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
+            mPublishFloater = LLFloaterReg::getTypedInstance<LLFloaterPublishClassified>(
                 "publish_classified", LLSD());
 
             mPublishFloater->setPublishClickedCallback(boost::bind
@@ -1526,47 +1523,3 @@ void LLPanelProfileClassified::updateTabLabel(const std::string& title)
         parent->setCurrentTabName(title);
     }
 }
-
-
-//-----------------------------------------------------------------------------
-// LLPublishClassifiedFloater
-//-----------------------------------------------------------------------------
-
-LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
- : LLFloater(key)
-{
-}
-
-LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
-{
-}
-
-BOOL LLPublishClassifiedFloater::postBuild()
-{
-    LLFloater::postBuild();
-
-    childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
-    childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
-
-    return TRUE;
-}
-
-void LLPublishClassifiedFloater::setPrice(S32 price)
-{
-    getChild<LLUICtrl>("price_for_listing")->setValue(price);
-}
-
-S32 LLPublishClassifiedFloater::getPrice()
-{
-    return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
-}
-
-void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
-{
-    getChild<LLButton>("publish_btn")->setClickedCallback(cb);
-}
-
-void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
-{
-    getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h
index 5f029b22f4a1ba4c7dc0ab5d7aed71db58688b46..e6aa761ff023c65fcda00198ad4a0abbe3b0466b 100644
--- a/indra/newview/llpanelprofileclassifieds.h
+++ b/indra/newview/llpanelprofileclassifieds.h
@@ -28,14 +28,11 @@
 #define LL_PANELPROFILECLASSIFIEDS_H
 
 #include "llavatarpropertiesprocessor.h"
-#include "llclassifiedinfo.h"
-#include "llfloater.h"
+#include "llfloaterpublishclassified.h"
 #include "llpanel.h"
 #include "llpanelavatar.h"
-#include "llrect.h"
 #include "lluuid.h"
 #include "v3dmath.h"
-#include "llcoros.h"
 #include "lleventcoro.h"
 
 class LLCheckBoxCtrl;
@@ -47,23 +44,6 @@ class LLTextEditor;
 class LLTextureCtrl;
 class LLUICtrl;
 
-
-class LLPublishClassifiedFloater final : public LLFloater
-{
-public:
-    LLPublishClassifiedFloater(const LLSD& key);
-    virtual ~LLPublishClassifiedFloater();
-
-    BOOL postBuild() override;
-
-    void setPrice(S32 price);
-    S32 getPrice();
-
-    void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
-    void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
-};
-
-
 /**
 * Panel for displaying Avatar's picks.
 */
@@ -325,11 +305,8 @@ class LLPanelProfileClassified
 
     S32 mPriceForListing;
 
-public:
     static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
 
-private:
-
     typedef std::list<LLPanelProfileClassified*> panel_list_t;
     static panel_list_t sAllPanels;
 
@@ -339,7 +316,7 @@ class LLPanelProfileClassified
     bool mCanClose;
     bool mEditOnLoad;
 
-    LLPublishClassifiedFloater* mPublishFloater;
+    LLFloaterPublishClassified* mPublishFloater;
 };
 
 #endif // LL_PANELPROFILECLASSIFIEDS_H
diff --git a/indra/newview/llpanelprofilelegacy.cpp b/indra/newview/llpanelprofilelegacy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..de6167984017908e9b8af14a5766c9fea5ec6b1d
--- /dev/null
+++ b/indra/newview/llpanelprofilelegacy.cpp
@@ -0,0 +1,1668 @@
+/*
+ * @file llpanelprofilelegacy.cpp
+ * @brief Legacy protocol avatar profile panel
+ *
+ * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelprofilelegacy.h"
+
+// libraries
+#include "llaccordionctrl.h"
+#include "llaccordionctrltab.h"
+#include "llavatarnamecache.h"
+#include "llcheckboxctrl.h"
+#include "llflatlistview.h"
+#include "llfloaterreg.h"
+#include "lllineeditor.h"
+#include "llloadingindicator.h"
+#include "llnotificationsutil.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltoggleablemenu.h"
+#include "lltrans.h"
+
+// newview
+#include "alavataractions.h"
+#include "llagent.h"
+#include "llagentdata.h"
+#include "llagentpicksinfo.h"
+#include "llavataractions.h"
+#include "llcallingcard.h" // for LLAvatarTracker
+#include "llclassifieditem.h"
+#include "lldateutil.h"
+#include "lldroptarget.h"
+#include "llfloaterreporter.h"
+#include "llfloaterworldmap.h"
+#include "llgroupactions.h"
+#include "llpanelclassified.h"
+#include "llpanelpick.h"
+#include "llpickitem.h"
+#include "llmutelist.h"
+#include "llsidetraypanelcontainer.h"
+#include "llslurl.h"
+#include "llviewerdisplayname.h"
+#include "llviewermenu.h" // gMenuHolder
+
+static constexpr std::string_view AGENT_PROFILE_CAP("AgentProfile");
+//static constexpr std::string_view UPLOAD_AGENT_PROFILE_CAP("UploadAgentProfileImage");
+
+// These are order-senstitive so don't fk with 'em!
+static const std::array<std::string, 8> sWantCheckboxes{{"wanna_build", "wanna_explore", "wanna_yiff", "wanna_work", "wanna_group", "wanna_buy", "wanna_sell", "wanna_hire"}};
+static const std::array<std::string, 6> sSkillsCheckboxes{{"can_texture", "can_architect", "can_model", "can_event", "can_script", "can_characters"}};
+
+static LLPanelInjector<LLPanelProfileLegacy> t_panel_lprofile("panel_profile_legacy_sidetray");
+static LLPanelInjector<LLPanelProfileLegacy::LLPanelProfileGroups> t_panel_group("panel_profile_legacy_groups");
+static LLPanelInjector<LLPanelProfileLegacy::LLPanelProfilePicks> t_panel_picks("panel_profile_legacy_picks");
+
+LLPanelProfileLegacy::LLPanelProfileLegacy()
+:   LLPanelProfileLegacyTab()
+,   mPanelPicks(nullptr)
+,   mPanelGroups(nullptr)
+{
+    mChildStack.setParent(this);
+    //mCommitCallbackRegistrar.add("Profile.CommitInterest", boost::bind(&LLPanelProfileLegacy::onCommitInterest, this));
+    mCommitCallbackRegistrar.add("Profile.CommitProperties", boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this));
+    mCommitCallbackRegistrar.add("Profile.CommitRights", boost::bind(&LLPanelProfileLegacy::onCommitRights, this));
+    mCommitCallbackRegistrar.add("Profile.CommitModifyObjectRights", boost::bind(&LLPanelProfileLegacy::onCommitModifyObjectsRights, this, _1));
+    mCommitCallbackRegistrar.add("Profile.Action", boost::bind(&LLPanelProfileLegacy::onCommitAction, this, _2));
+    mEnableCallbackRegistrar.add("Profile.Enable", boost::bind(&LLPanelProfileLegacy::isActionEnabled, this, _2));
+}
+
+LLPanelProfileLegacy::~LLPanelProfileLegacy()
+{
+    if (LLAvatarPropertiesProcessor::instanceExists() && LLPanelProfileLegacyTab::getAvatarId().notNull())
+        LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLPanelProfileLegacyTab::getAvatarId(), this);
+    if (mAvatarNameCacheConnection.connected())
+        mAvatarNameCacheConnection.disconnect();
+    if (mNameChangedConnection.connected())
+        mNameChangedConnection.disconnect();
+}
+
+// virtual
+BOOL LLPanelProfileLegacy::postBuild()
+{
+    mPanelGroups = static_cast<LLPanelProfileGroups*>(getChild<LLUICtrl>("avatar_groups_tab_panel"));
+    mPanelPicks = static_cast<LLPanelProfilePicks*>(getChild<LLUICtrl>("avatar_picks_tab_panel"));
+    mPanelPicks->setProfilePanel(this);
+
+    if (dynamic_cast<LLSideTrayPanelContainer*>(getParent()) != nullptr)
+        getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onBackBtnClick, this));
+    else if (dynamic_cast<LLFloater*>(getParent()) != nullptr)
+        getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::closeParentFloater, this));
+    else
+        getChild<LLUICtrl>("back")->setEnabled(FALSE);
+    getChild<LLTextEditor>("sl_about")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this));
+    getChild<LLTextEditor>("fl_about")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this));
+    getChild<LLTextureCtrl>("sl_profile_pic")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this));
+    getChild<LLTextureCtrl>("fl_profile_pic")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitAvatarProperties, this));
+    getChild<LLTextEditor>("notes")->setCommitCallback(boost::bind(&LLPanelProfileLegacy::onCommitNotes, this, _1));
+    getChild<LLTextEditor>("avatar_name")->setDoubleClickCallback(boost::bind(&LLPanelProfileLegacy::onDoubleClickName, this));
+    return TRUE;
+}
+
+// virtual
+void LLPanelProfileLegacy::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+    // Temporarily add saved children back and reshape them.
+    mChildStack.preParentReshape();
+    LLPanel::reshape(width, height, called_from_parent);
+    mChildStack.postParentReshape();
+}
+
+// virtual
+void LLPanelProfileLegacy::onOpen(const LLSD& key)
+{
+    if (!key.has("avatar_id")) return;
+    const LLUUID av_id = key["avatar_id"].asUUID();
+
+    if (key.has("action"))
+    {
+        // *TODO: Actions, if any
+        return;
+    }
+
+    if (mNameChangedConnection.connected())
+    {
+        mNameChangedConnection.disconnect();
+    }
+
+    setAvatarId(av_id);
+
+    mPanelGroups->onOpen(LLSD(av_id));
+    mPanelPicks->onOpen(LLSD(av_id));
+    // Oh joy!
+    bool is_self = (getAvatarId() == gAgentID);
+    getChild<LLView>("sl_profile_pic")->setEnabled(is_self);
+    getChild<LLView>("fl_profile_pic")->setEnabled(is_self);
+    getChild<LLView>("sl_about")->setEnabled(is_self);
+    getChild<LLView>("fl_about")->setEnabled(is_self);
+    getChild<LLView>("www")->setVisible(!is_self);
+    getChild<LLView>("www_edit")->setVisible(is_self);
+    getChild<LLView>("allow_publish")->setVisible(is_self);
+    //childSetEnabled("wanna_something", is_self);
+    //childSetEnabled("can_something", is_self);
+    //childSetEnabled("languages", is_self);
+    for (const std::string& checkbox: sWantCheckboxes)
+        childSetEnabled(checkbox, is_self);
+    for (const std::string& checkbox: sSkillsCheckboxes)
+        childSetEnabled(checkbox, is_self);
+    childSetEnabled("drop_target", !is_self);
+    getChild<LLLayoutPanel>("avatar_in_search", is_self);
+    getChild<LLDropTarget>("drop_target")->setAgentID(av_id);
+    //resetInterestsControlValues();
+
+    updateData();
+    resetControls();
+
+    getChild<LLAccordionCtrl>("avatar_accordion")->expandDefaultTab();
+}
+
+void LLPanelProfileLegacy::resetControls()
+{
+    LLButton* button = getChild<LLButton>("btn_chat");
+    button->setEnabled(getAvatarId() != gAgentID);
+    button = getChild<LLButton>("btn_friend");
+    button->setEnabled(getAvatarId() != gAgentID);
+    button->setLabel(getString((LLAvatarTracker::instance().getBuddyInfo(getAvatarId()) == nullptr)
+                               ? "add_friend" : "remove_friend"));
+    button = getChild<LLButton>("btn_block");
+    button->setEnabled(getAvatarId() != gAgentID);
+    button->setLabel(LLTrans::getString(LLMuteList::getInstance()->isMuted(getAvatarId())
+                                        ? "UnmuteAvatar"
+                                        : "MuteAvatar"));
+}
+
+//void LLPanelProfileLegacy::resetInterestsControlValues()
+//{
+//    for (U32 i = 0; i < sWantCheckboxes.size(); ++i)
+//    {
+//        getChild<LLCheckBoxCtrl>(sWantCheckboxes.at(i))->setValue(FALSE);
+//    }
+//
+//    for (U32 i = 0; i < sSkillsCheckboxes.size(); ++i)
+//    {
+//        getChild<LLCheckBoxCtrl>(sSkillsCheckboxes.at(i))->setValue(FALSE);
+//    }
+//    getChild<LLLineEditor>("wanna_something")->setText(LLStringUtil::null);
+//    getChild<LLLineEditor>("can_something")->setText(LLStringUtil::null);
+//    getChild<LLLineEditor>("languages")->setText(LLStringUtil::null);
+//}
+
+void LLPanelProfileLegacy::updateData()
+{
+    setProgress(true);
+
+    const std::string cap_url = gAgent.getRegionCapability(AGENT_PROFILE_CAP);
+    if (!cap_url.empty())
+    {
+        const auto& agent_id = getAvatarId();
+        auto handle = getHandle();
+        LLCoros::instance().launch("requestAvatarProfileCoro", [cap_url, agent_id, handle]() {
+            LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+            LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+                httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy));
+            LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+            LLCore::HttpHeaders::ptr_t httpHeaders;
+
+            LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+            httpOpts->setFollowRedirects(true);
+
+            std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+            LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+            LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+            LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+            LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL;
+
+            if (!status
+                || !result.has("id")
+                || agent_id != result["id"].asUUID())
+            {
+                LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+                return;
+            }
+
+            if (handle.isDead())
+            {
+                // panel is dead
+                return;
+            }
+
+            LLPanelProfileLegacy* legacy_sidetray = (LLPanelProfileLegacy*)handle.get();
+            if (!legacy_sidetray)
+            {
+                return;
+            }
+
+            // AgentProfile dumps all results into a big ol' map. Let's build some structs and make a bunch of calls
+            // to processProperties()
+            LLAvatarData avatar_data;
+
+            avatar_data.agent_id = agent_id;
+            avatar_data.avatar_id = agent_id;
+            avatar_data.image_id = result["sl_image_id"].asUUID();
+            avatar_data.fl_image_id = result["fl_image_id"].asUUID();
+            avatar_data.partner_id = result["partner_id"].asUUID();
+            avatar_data.about_text = result["sl_about_text"].asString();
+            avatar_data.fl_about_text = result["fl_about_text"].asString();
+            avatar_data.born_on = result["member_since"].asDate();
+            avatar_data.profile_url = result.has("home_page")
+                ? result["home_page"].asString() : getProfileURL(agent_id.asString());
+
+            avatar_data.flags = 0;
+            if (result["online"].asBoolean())
+            {
+                avatar_data.flags |= AVATAR_ONLINE;
+            }
+            if (result["allow_publish"].asBoolean())
+            {
+                avatar_data.flags |= AVATAR_ALLOW_PUBLISH;
+            }
+            if (result["identified"].asBoolean())
+            {
+                avatar_data.flags |= AVATAR_IDENTIFIED;
+            }
+            if (result["transacted"].asBoolean())
+            {
+                avatar_data.flags |= AVATAR_TRANSACTED;
+            }
+
+            avatar_data.caption_index = 0;
+            if (result.has("charter_member"))  // won't be present if "caption" is set
+            {
+                avatar_data.caption_index = result["charter_member"].asInteger();
+            }
+            else if (result.has("caption"))
+            {
+                avatar_data.caption_text = result["caption"].asString();
+            }
+            legacy_sidetray->processProperties(&avatar_data, APT_PROPERTIES);
+
+            LLSD groups_array = result["groups"];
+            LLAvatarGroups avatar_groups;
+            avatar_groups.agent_id = agent_id;
+            avatar_groups.avatar_id = agent_id;
+
+            for (LLSD::array_const_iterator it = groups_array.beginArray();
+                it != groups_array.endArray(); ++it)
+            {
+                const LLSD& group_info = *it;
+                LLAvatarGroups::LLGroupData group_data;
+                group_data.group_powers = 0;
+                group_data.group_title = group_info["name"].asString();
+                group_data.group_id = group_info["id"].asUUID();
+                group_data.group_name = group_info["name"].asString();
+                group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+                avatar_groups.group_list.push_back(group_data);
+            }
+
+            auto* groups_panel = static_cast<LLPanelProfileGroups*>(legacy_sidetray->getChild<LLUICtrl>("avatar_groups_tab_panel"));
+
+            groups_panel->processProperties(&avatar_groups, APT_GROUPS);
+            legacy_sidetray->processProperties(&avatar_groups, APT_GROUPS);
+
+            LLAvatarNotes avatar_notes;
+            avatar_notes.agent_id = agent_id;
+            avatar_notes.target_id = agent_id;
+            avatar_notes.notes = result["notes"].asString();
+
+            legacy_sidetray->processProperties(&avatar_notes, APT_NOTES);
+
+            LLSD picks_array = result["picks"];
+            LLAvatarPicks avatar_picks;
+            avatar_picks.agent_id = agent_id;
+            avatar_picks.target_id = agent_id;
+            for (LLSD::array_const_iterator it = picks_array.beginArray();
+                it != picks_array.endArray(); ++it)
+            {
+                const LLSD& pick_data = *it;
+                avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+            }
+
+            legacy_sidetray->processProperties(&avatar_picks, APT_PICKS);
+
+            // bonus time...
+            if (result.has("customer_type"))
+            {
+                LLUICtrl* internal_icon = legacy_sidetray->getChild<LLUICtrl>("account_type_internal");
+                LLUICtrl* premium_icon = legacy_sidetray->getChild<LLUICtrl>("account_type_premium");
+                LLUICtrl* plus_icon = legacy_sidetray->getChild<LLUICtrl>("account_type_plus");
+                const std::string& type = result["customer_type"].asStringRef();
+
+                if (type == "Internal")
+                {
+                    internal_icon->setVisible(true);
+                    premium_icon->setVisible(false);
+                    plus_icon->setVisible(false);
+                }
+                else if (type == "Monthly" || type == "Quarterly" || type == "Annual")
+                {
+                    internal_icon->setVisible(false);
+                    premium_icon->setVisible(true);
+                    plus_icon->setVisible(false);
+                }
+                else if (type.substr(0, 12) == "Premium_Plus")
+                {
+                    internal_icon->setVisible(false);
+                    premium_icon->setVisible(false);
+                    plus_icon->setVisible(true);
+                }
+                else /* if (type == "Base") */
+                {
+                    internal_icon->setVisible(false);
+                    premium_icon->setVisible(false);
+                    plus_icon->setVisible(false);
+                }
+            }
+
+            });
+    }
+
+    mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(),
+        boost::bind(&LLPanelProfileLegacy::onAvatarNameCache, this, _1, _2));
+
+    const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+    bool is_other = (relation && getAvatarId() != gAgentID);
+    getChild<LLLayoutPanel>("avatar_perm")->setVisible(is_other);
+    if (is_other)
+    {
+        S32 rights = relation->getRightsGrantedTo();
+        getChild<LLCheckBoxCtrl>("allow_show_online")->setValue(rights & LLRelationship::GRANT_ONLINE_STATUS ? TRUE : FALSE);
+        getChild<LLCheckBoxCtrl>("allow_mapping")->setValue(rights & LLRelationship::GRANT_MAP_LOCATION ? TRUE : FALSE);
+        getChild<LLCheckBoxCtrl>("allow_object_perms")->setValue(rights & LLRelationship::GRANT_MODIFY_OBJECTS ? TRUE : FALSE);
+    }
+}
+
+void LLPanelProfileLegacy::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+    getChild<LLTextEditor>("avatar_name")->setText(av_name.getCompleteName());
+}
+
+void LLPanelProfileLegacy::sendAvatarProfileCoro(std::string url, LLSD payload)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("send_avatar_profile_coro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpHeaders::ptr_t httpHeaders;
+
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+    httpOpts->setFollowRedirects(true);
+
+    std::string full_url = url + "/" + getAvatarId().asString();
+
+    LLSD result = httpAdapter->putAndSuspend(httpRequest, full_url, payload, httpOpts, httpHeaders);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("LegacyProfiles") << "Failed to put agent information " << payload << " for id " << getAvatarId() << LL_ENDL;
+        return;
+    }
+
+    LL_DEBUGS("LegacyProfiles") << "Agent id: " << getAvatarId() << " Payload: " << payload << " Result: " << httpResults << LL_ENDL;
+}
+
+void LLPanelProfileLegacy::processProperties(void* data, EAvatarProcessorType type)
+{
+    if (!data) return;
+    switch(type)
+    {
+        case APT_PROPERTIES:
+        {
+            const LLAvatarData* pData = static_cast<const LLAvatarData*>(data);
+            if (!pData || pData->avatar_id != getAvatarId()) return;
+            getChild<LLTextureCtrl>("sl_profile_pic")->setValue(pData->image_id);
+            getChild<LLTextureCtrl>("fl_profile_pic")->setValue(pData->fl_image_id);
+            if (pData->partner_id.notNull())
+            {
+                getChild<LLTextBase>("partner_info")->setText(LLSLURL("agent", pData->partner_id, "inspect").getSLURLString());
+                getChild<LLTextBase>("partner_label")->setVisible(TRUE);
+                getChild<LLTextBase>("partner_info")->setVisible(TRUE);
+            }
+            else
+            {
+                getChild<LLTextBase>("partner_label")->setVisible(FALSE);
+                getChild<LLTextBase>("partner_info")->setVisible(FALSE);
+            }
+            getChild<LLTextEditor>("sl_about")->setText(pData->about_text);
+            getChild<LLTextEditor>("fl_about")->setText(pData->fl_about_text);
+            getChild<LLTextBase>("www")->setText(pData->profile_url);
+            getChild<LLLineEditor>("www_edit")->setText(pData->profile_url);
+
+            LLStringUtil::format_map_t args;
+            std::string birth_date = LLTrans::getString("AvatarBirthDateFormatFull");
+            LLStringUtil::format(birth_date, LLSD().with("datetime", static_cast<S32>(pData->born_on.secondsSinceEpoch())));
+            args["[AGE]"] = LLDateUtil::ageFromDate(pData->born_on, LLDate::now());
+            args["[REZDAY]"] = birth_date;
+            args["[ACCOUNT_TYPE]"] = LLAvatarPropertiesProcessor::accountType(pData);
+            args["[PAYMENT_INFO]"] = LLAvatarPropertiesProcessor::paymentInfo(pData);
+            args["[AGE_VERIFIED]"] = pData->flags & AVATAR_AGEVERIFIED ? getString("age_verified") : LLStringUtil::null;
+            LLSD formatted_info(getString("account_info_fmt", args));
+            getChild<LLTextBase>("account_info")->setValue(formatted_info);
+            formatted_info = LLSD(getString("rezday_fmt", args));
+            getChild<LLTextBase>("rezday")->setValue(formatted_info);
+            getChild<LLView>("cake")->setVisible(pData->born_on.toHTTPDateString(LLStringExplicit("%d %b")) ==
+                            LLDate::now().toHTTPDateString(LLStringExplicit("%d %b")));
+            getChild<LLCheckBoxCtrl>("allow_publish")->setValue(static_cast<bool>(pData->flags & AVATAR_ALLOW_PUBLISH));
+            getChild<LLUICtrl>("online")->setVisible(static_cast<BOOL>(pData->flags & AVATAR_ONLINE ||
+                                                                       pData->avatar_id == gAgentID));
+            break;
+        }
+        case APT_NOTES:
+        {
+            const LLAvatarNotes* pData = static_cast<const LLAvatarNotes*>(data);
+            if (!pData || pData->target_id != getAvatarId()) return;
+            getChild<LLTextEditor>("notes")->setValue(pData->notes);
+            break;
+        }
+        //case APT_INTERESTS:
+        //{
+        //    const LLAvatarInterests* pData = static_cast<const LLAvatarInterests*>(data);
+        //    if (!pData || pData->avatar_id != getAvatarId()) return;
+
+        //    for (U32 i = 0; i < sWantCheckboxes.size(); ++i)
+        //    {
+        //        getChild<LLCheckBoxCtrl>(sWantCheckboxes.at(i))->setValue(pData->want_to_mask & (1<<i) ? TRUE : FALSE);
+        //    }
+
+        //    for (U32 i = 0; i < sSkillsCheckboxes.size(); ++i)
+        //    {
+        //        getChild<LLCheckBoxCtrl>(sSkillsCheckboxes.at(i))->setValue(pData->skills_mask & (1<<i) ? TRUE : FALSE);
+        //    }
+        //    getChild<LLLineEditor>("wanna_something")->setText(pData->want_to_text);
+        //    getChild<LLLineEditor>("can_something")->setText(pData->skills_text);
+        //    getChild<LLLineEditor>("languages")->setText(pData->languages_text);
+        //    break;
+        //}
+        case APT_GROUPS:
+        {
+            const LLAvatarGroups* pData = static_cast<LLAvatarGroups*>(data);
+            if(!pData || getAvatarId() != pData->avatar_id) return;
+
+            showTab("avatar_groups_tab", !pData->group_list.empty());
+            break;
+        }
+        // These are handled by their respective panels
+        case APT_PICKS:
+        case APT_CLASSIFIEDS:
+        case APT_PICK_INFO:
+        case APT_CLASSIFIED_INFO:
+        // Used by LLAgent not profiles. ;)
+        case APT_TEXTURES:
+        default:
+            break;
+    }
+    setProgress(false);
+}
+
+void LLPanelProfileLegacy::setProgress(bool started)
+{
+    LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator");
+    indicator->setVisible(started);
+    if (started)
+        indicator->start();
+    else
+        indicator->stop();
+}
+
+void LLPanelProfileLegacy::showTab(std::string_view name, bool show) const
+{
+    getChild<LLAccordionCtrlTab>(name)->setVisible(show);
+    getChild<LLAccordionCtrl>("avatar_accordion")->arrange();
+}
+
+LLPanel* LLPanelProfileLegacy::expandTab(const std::string& name) const
+{
+    getChild<LLAccordionCtrl>("avatar_accordion")->expandTab(name);
+    return getChild<LLAccordionCtrlTab>(name)->getChild<LLPanel>(name + "_panel");
+}
+
+LLPanel* LLPanelProfileLegacy::getExpandedTab() const
+{
+    const LLAccordionCtrlTab* tab = getChild<LLAccordionCtrl>("avatar_accordion")->getExpandedTab();
+    return tab ? tab->getChild<LLPanel>(tab->getName() + "_panel") : nullptr;
+}
+
+void LLPanelProfileLegacy::onCommitAction(const LLSD& userdata)
+{
+    const std::string action = userdata.asString();
+    if (action == "friend")
+    {
+        if (LLAvatarTracker::instance().getBuddyInfo(getAvatarId()) == nullptr)
+            LLAvatarActions::requestFriendshipDialog(getAvatarId());
+        else
+            LLAvatarActions::removeFriendDialog(getAvatarId());
+        resetControls();
+    }
+    else if (action == "block")
+    {
+        LLAvatarActions::toggleBlock(getAvatarId());
+        resetControls();
+    }
+    else if (action == "chat")
+        LLAvatarActions::startIM(getAvatarId());
+    else if (action == "call")
+        LLAvatarActions::startCall(getAvatarId());
+    else if (action == "share")
+        LLAvatarActions::share(getAvatarId());
+    else if (action == "teleport")
+        LLAvatarActions::offerTeleport(getAvatarId());
+    else if (action == "req_teleport")
+        LLAvatarActions::teleportRequest(getAvatarId());
+    else if (action == "map")
+        LLAvatarActions::showOnMap(getAvatarId());
+    else if (action == "pay")
+        LLAvatarActions::pay(getAvatarId());
+    else if (action == "report_abuse")
+        LLFloaterReporter::showFromObject(getAvatarId());
+    else if (action == "upload_sl")
+    {
+        // *TODO:
+    }
+    else if (action == "upload_fl")
+    {
+        // *TODO:
+    }
+    else if (action == "webprofile")
+        ALAvatarActions::showWebProfile(getAvatarId());
+    else
+        LL_WARNS("LegacyProfiles") << "Unhandled action: " << action << LL_ENDL;
+}
+
+bool LLPanelProfileLegacy::isActionEnabled(const LLSD& userdata)
+{
+    bool action_enabled = false;
+    const std::string check = userdata.asString();
+    if (check == "can_has_telefono")
+        action_enabled = (LLAvatarActions::canCall() && getAvatarId() != gAgentID);
+    else if (check == "can_has_teleport")
+        action_enabled = (LLAvatarActions::canOfferTeleport(getAvatarId()) && getAvatarId() != gAgentID);
+    else if (check == "can_has_map")
+    {
+        action_enabled = (LLAvatarTracker::instance().isBuddyOnline(getAvatarId())
+                          && LLAvatarActions::isAgentMappable(getAvatarId()))
+        || gAgent.isGodlike();
+    }
+    else if (check == "can_has_pay")
+        action_enabled = (getAvatarId() != gAgentID);
+    else if (check == "can_share")
+        action_enabled = (getAvatarId() != gAgentID);
+    else if (check == "can_drama")
+        action_enabled = (getAvatarId() != gAgentID);
+    else if (check == "can_upload_pic")
+    {
+        action_enabled = getAvatarId() == gAgentID
+            && !gAgent.getRegionCapability("UploadAgentProfileImage").empty();
+    }
+    else
+        LL_INFOS("LegacyProfiles") << "Unhandled check " << check << LL_ENDL;
+    return action_enabled;
+}
+
+void LLPanelProfileLegacy::onCommitAvatarProperties()
+{
+    if (getAvatarId() != gAgentID) return;
+
+
+    std::string cap = gAgent.getRegionCapability(AGENT_PROFILE_CAP);
+    if (!cap.empty())
+    {
+        LLSD data;
+        data["sl_about_text"] = getChild<LLTextEditor>("sl_about")->getText();
+        data["fl_about_text"] = getChild<LLTextEditor>("fl_about")->getText();
+        data["profile_url"]   = getChild<LLLineEditor>("www_edit")->getText();
+        data["allow_publish"] = getChild<LLCheckBoxCtrl>("allow_publish")->getValue().asBoolean();
+
+        LLCoros::instance().launch(
+            "sendAvatarProfileCoro",
+            boost::bind(&LLPanelProfileLegacy::sendAvatarProfileCoro, this, cap, data));
+    }
+}
+
+void LLPanelProfileLegacy::onCommitNotes(LLUICtrl* ctrl)
+{
+    std::string cap = gAgent.getRegionCapability(AGENT_PROFILE_CAP);
+    if (!cap.empty())
+    {
+        LLCoros::instance().launch("sendAvatarProfileCoro",
+            boost::bind(&LLPanelProfileLegacy::sendAvatarProfileCoro, this, cap,
+            LLSD().with("notes", ctrl->getValue().asString())));
+    }
+}
+
+void LLPanelProfileLegacy::onDoubleClickName()
+{
+    if (getAvatarId() == gAgentID)
+    {
+        LLFloaterReg::showInstance("display_name");
+        mNameChangedConnection = LLViewerDisplayName::addNameChangedCallback(boost::bind(&LLPanelProfileLegacy::onNameChanged, this));
+    }
+}
+
+void LLPanelProfileLegacy::onNameChanged()
+{
+    mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(),
+                                                        boost::bind(&LLPanelProfileLegacy::onAvatarNameCache, this, _1, _2));
+}
+
+void LLPanelProfileLegacy::onBackBtnClick()
+{
+    LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
+    if(parent)
+    {
+        parent->openPreviousPanel();
+    }
+}
+
+void LLPanelProfileLegacy::onCommitModifyObjectsRights(LLUICtrl* ctrl)
+{
+    if (ctrl->getValue().asBoolean()) // We want to confirm that the user really wants to grant object rights
+    {
+        LLNotificationsUtil::add("GrantModifyRights",
+                                 LLSD().with("NAME", LLSLURL("agent", getAvatarId(), "inspect").getSLURLString()),
+                                 LLSD(),
+                                 boost::bind(&LLPanelProfileLegacy::handleConfirmModifyRightsCallback, this, _1, _2));
+    }
+    else // No confirmation needed on removing rights
+    {
+        onCommitRights();
+    }
+}
+
+bool LLPanelProfileLegacy::handleConfirmModifyRightsCallback(const LLSD& notification, const LLSD& response)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+    if (option == 0)
+    {
+        onCommitRights();
+        return true;
+    }
+    // Make sure to flip the checkbox back off
+    findChild<LLCheckBoxCtrl>("allow_object_perms")->setValue(false);
+    return false;
+}
+
+void LLPanelProfileLegacy::closeParentFloater()
+{
+    LLFloater* floater = dynamic_cast<LLFloater*>(getParent());
+    if (floater) floater->closeFloater();
+}
+
+void LLPanelProfileLegacy::onCommitRights()
+{
+    if (!LLAvatarActions::isFriend(getAvatarId())) return;
+    S32 flags = 0;
+    if (getChild<LLCheckBoxCtrl>("allow_show_online")->getValue().asBoolean())
+        flags |= LLRelationship::GRANT_ONLINE_STATUS;
+    if (getChild<LLCheckBoxCtrl>("allow_mapping")->getValue().asBoolean())
+        flags |= LLRelationship::GRANT_MAP_LOCATION;
+    if (getChild<LLCheckBoxCtrl>("allow_object_perms")->getValue().asBoolean())
+        flags |= LLRelationship::GRANT_MODIFY_OBJECTS;
+
+    LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(), flags);
+}
+
+void LLPanelProfileLegacy::openPanel(LLPanel* panel, const LLSD& params)
+{
+    // Hide currently visible panel.
+    mChildStack.push();
+
+    // Add the panel or bring it to front.
+    if (panel->getParent() != this)
+    {
+        addChild(panel);
+    }
+    else
+    {
+        sendChildToFront(panel);
+    }
+
+    panel->setVisible(TRUE);
+    panel->setFocus(TRUE); // prevent losing focus by the floater
+    panel->onOpen(params);
+
+    LLRect new_rect = getRect();
+    panel->reshape(new_rect.getWidth(), new_rect.getHeight());
+    new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
+    panel->setRect(new_rect);
+}
+
+void LLPanelProfileLegacy::closePanel(LLPanel* panel)
+{
+    panel->setVisible(FALSE);
+
+    if (panel->getParent() == this)
+    {
+        removeChild(panel);
+
+        // Make the underlying panel visible.
+        mChildStack.pop();
+
+        // Prevent losing focus by the floater
+        const child_list_t* child_list = getChildList();
+        if (!child_list->empty())
+        {
+            child_list->front()->setFocus(TRUE);
+        }
+        else
+        {
+            LL_WARNS() << "No underlying panel to focus." << LL_ENDL;
+        }
+    }
+}
+
+// LLPanelProfilePicks //
+LLPanelProfileLegacy::LLPanelProfilePicks::LLPanelProfilePicks()
+:   LLPanelProfileLegacyTab()
+,   mProfilePanel(nullptr)
+,   mClassifiedsList(nullptr)
+,   mPicksList(nullptr)
+,   mPanelPickEdit(nullptr)
+,   mPanelPickInfo(nullptr)
+,   mPanelClassifiedInfo(nullptr)
+,   mPopupMenuHandle()
+,   mPlusMenuHandle()
+{
+}
+
+LLPanelProfileLegacy::LLPanelProfilePicks::~LLPanelProfilePicks()
+{
+    auto popup_menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
+    auto plus_menu = mPlusMenuHandle.get();
+    if (popup_menu)
+    {
+        popup_menu->die();
+        mPopupMenuHandle.markDead();
+    }
+
+    if (plus_menu)
+    {
+        plus_menu->die();
+        mPlusMenuHandle.markDead();
+    }
+}
+
+BOOL LLPanelProfileLegacy::LLPanelProfilePicks::postBuild()
+{
+    mPicksList = getChild<LLFlatListView>("picks_list");
+    mClassifiedsList = getChild<LLFlatListView>("classifieds_list");
+    childSetAction("add_btn", boost::bind(&LLPanelProfilePicks::onClickPlusBtn, this));
+    childSetAction("teleport_btn", boost::bind(&LLPanelProfilePicks::onClickTeleport, this));
+    childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePicks::onClickShowOnMap, this));
+    childSetAction("info_btn", boost::bind(&LLPanelProfilePicks::onClickInfo, this));
+
+    // setup menu
+    CommitCallbackRegistry::ScopedRegistrar registar;
+    registar.add("Pick.Info", boost::bind(&LLPanelProfilePicks::onClickInfo, this));
+    registar.add("Pick.Edit", boost::bind(&LLPanelProfilePicks::onPanelEdit, this));
+    registar.add("Pick.Teleport", boost::bind(&LLPanelProfilePicks::onClickTeleport, this));
+    registar.add("Pick.Map", boost::bind(&LLPanelProfilePicks::onClickShowOnMap, this));
+    registar.add("Pick.Delete", boost::bind(&LLPanelProfilePicks::onClickDelete, this));
+    //EnableCallbackRegistry::ScopedRegistrar enable_registar;
+    //enable_registar.add("Pick.Enable", boost::bind(&LLPanelProfilePicks::onEnableMenuItem, this, _2));
+
+    auto popup_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, child_registry_t::instance());
+    if (popup_menu)
+        mPopupMenuHandle = popup_menu->getHandle();
+
+    CommitCallbackRegistry::ScopedRegistrar plus_registar;
+    plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelProfilePicks::onPlusMenuItemClicked, this, _2));
+    mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelProfilePicks::isActionEnabled, this, _2));
+    auto plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, child_registry_t::instance());
+    if (plus_menu)
+        mPlusMenuHandle = plus_menu->getHandle();
+
+    updateButtons();
+    return TRUE;
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onOpen(const LLSD& key)
+{
+    const LLUUID id(key.asUUID());
+    BOOL self = (gAgent.getID() == id);
+
+    setAvatarId(id);
+    updateData();
+
+    getChild<LLView>("add_btn_lp")->setVisible(self);
+    auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
+    if (menu)
+    {
+        menu->setItemVisible("pick_delete", self);
+        menu->setItemVisible("pick_edit", self);
+        menu->setItemVisible("pick_separator", self);
+    }
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::updateData()
+{
+    mPicksList->clear();
+    mClassifiedsList->clear();
+    LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId());
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type)
+{
+    if (APT_PICKS == type)
+    {
+        mPicksList->clear();
+        LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
+        if (!avatar_picks || getAvatarId() != avatar_picks->target_id) return;
+        for (const LLAvatarPicks::pick_data_t& pick: avatar_picks->picks_list)
+        {
+            const LLUUID pick_id = pick.first;
+            const std::string pick_name = pick.second;
+
+            LLPickItem* picture = LLPickItem::create();
+            picture->childSetAction("info_chevron", boost::bind(&LLPanelProfilePicks::onClickInfo, this));
+            picture->setPickName(pick_name);
+            picture->setPickId(pick_id);
+            picture->setCreatorId(getAvatarId());
+
+            LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
+            picture->update();
+
+            LLSD pick_value = LLSD();
+            pick_value.insert(PICK_ID, pick_id);
+            pick_value.insert(PICK_NAME, pick_name);
+            pick_value.insert(PICK_CREATOR_ID, getAvatarId());
+
+            mPicksList->addItem(picture, pick_value);
+            picture->setMouseUpCallback(boost::bind(&LLPanelProfilePicks::updateButtons, this));
+            picture->setRightMouseUpCallback(boost::bind(&LLPanelProfilePicks::onRightMouseUpItem, this, _1, _2, _3, _4));
+        }
+        showAccordion("tab_picks", mPicksList->size());
+    }
+    else if (APT_CLASSIFIEDS == type)
+    {
+        mClassifiedsList->clear();
+        LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
+        if (!c_info || getAvatarId() != c_info->target_id) return;
+        for (const LLAvatarClassifieds::classified_data& c_data: c_info->classifieds_list)
+        {
+            LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id);
+            c_item->childSetAction("info_chevron", boost::bind(&LLPanelProfilePicks::onClickInfo, this));
+            c_item->setClassifiedName(c_data.name);
+
+            LLSD pick_value = LLSD();
+            pick_value.insert(CLASSIFIED_ID, c_data.classified_id);
+            pick_value.insert(CLASSIFIED_NAME, c_data.name);
+
+            if (!findClassifiedById(c_data.classified_id))
+            {
+                mClassifiedsList->addItem(c_item, pick_value);
+            }
+            c_item->setMouseUpCallback(boost::bind(&LLPanelProfilePicks::updateButtons, this));
+            c_item->setRightMouseUpCallback(boost::bind(&LLPanelProfilePicks::onRightMouseUpItem, this, _1, _2, _3, _4));
+        }
+        showAccordion("tab_classifieds", mClassifiedsList->size());
+    }
+    updateButtons();
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::showAccordion(const std::string& name, bool show)
+{
+    getChild<LLAccordionCtrlTab>(name)->setVisible(show);
+    LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion");
+    acc->arrange();
+}
+
+LLClassifiedItem *LLPanelProfileLegacy::LLPanelProfilePicks::findClassifiedById(const LLUUID& classified_id) const
+{
+    // HACK - find item by classified id.  Should be a better way.
+    std::vector<LLPanel*> items;
+    mClassifiedsList->getItems(items);
+    LLClassifiedItem* c_item = nullptr;
+    for(LLPanel* it: items)
+    {
+        LLClassifiedItem *test_item = dynamic_cast<LLClassifiedItem*>(it);
+        if (test_item && test_item->getClassifiedId() == classified_id)
+        {
+            c_item = test_item;
+            break;
+        }
+    }
+    return c_item;
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::updateButtons()
+{
+    bool has_selected = (mPicksList->numSelected() > 0||
+                         mClassifiedsList->numSelected() > 0);
+
+    getChildView("info_btn")->setEnabled(has_selected);
+    getChildView("teleport_btn")->setEnabled(has_selected);
+    getChildView("show_on_map_btn")->setEnabled(has_selected);
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onClickInfo()
+{
+    if(mClassifiedsList->numSelected() > 0)
+        openClassifiedInfo();
+    else if(mPicksList->numSelected() > 0)
+        openPickInfo();
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onClickPlusBtn()
+{
+    auto menu = mPlusMenuHandle.get();
+    if (menu)
+    {
+        LLRect rect(getChildView("add_btn")->getRect());
+        menu->setButtonRect(rect, this);
+        LLMenuGL::showPopup(this, menu, rect.mLeft, rect.mTop);
+    }
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onClickTeleport()
+{
+    LLPickItem* pick_item = static_cast<LLPickItem*>(mPicksList->getSelectedItem());
+    LLClassifiedItem* c_item = getSelectedClassifiedItem();
+
+    LLVector3d pos;
+    if (pick_item)
+    {
+        pos = pick_item->getPosGlobal();
+    }
+    else if (c_item)
+    {
+        pos = c_item->getPosGlobal();
+        LLPanelClassifiedInfo::sendClickMessage("teleport", false,
+                                                c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
+    }
+
+    if (!pos.isExactlyZero())
+    {
+        gAgent.teleportViaLocation(pos);
+        LLFloaterWorldMap::getInstance()->trackLocation(pos);
+    }
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onClickShowOnMap()
+{
+    LLPickItem* pick_item = static_cast<LLPickItem*>(mPicksList->getSelectedItem());
+    LLClassifiedItem* c_item = getSelectedClassifiedItem();
+
+    LLVector3d pos;
+    if (pick_item)
+    {
+        pos = pick_item->getPosGlobal();
+    }
+    else if (c_item)
+    {
+        LLPanelClassifiedInfo::sendClickMessage("map", false,
+                                                c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
+        pos = c_item->getPosGlobal();
+    }
+
+    LLFloaterWorldMap::getInstance()->trackLocation(pos);
+    LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onClickDelete()
+{
+    LLSD value = mPicksList->getSelectedValue();
+    if (value.isDefined())
+    {
+        LLSD args;
+        args["PICK"] = value[PICK_NAME];
+        LLNotificationsUtil::add("ProfileDeletePick", args, LLSD(),
+            boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2));
+        return;
+    }
+    value = mClassifiedsList->getSelectedValue();
+    if (value.isDefined())
+    {
+        LLSD args;
+        args["CLASSIFIED"] = value[CLASSIFIED_NAME];
+        LLNotificationsUtil::add("ProfileDeleteClassified", args, LLSD(),
+            boost::bind(&LLPanelProfilePicks::callbackDeleteClassified, this, _1, _2));
+        return;
+    }
+}
+
+bool LLPanelProfileLegacy::LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+    LLSD pick_value = mPicksList->getSelectedValue();
+
+    if (0 == option)
+    {
+        LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
+        mPicksList->removeItemByValue(pick_value);
+    }
+    updateButtons();
+    return false;
+}
+
+bool LLPanelProfileLegacy::LLPanelProfilePicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+    LLSD value = mClassifiedsList->getSelectedValue();
+
+    if (0 == option)
+    {
+        LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
+        mClassifiedsList->removeItemByValue(value);
+    }
+    updateButtons();
+    return false;
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::openPickInfo()
+{
+    LLSD selected_value = mPicksList->getSelectedValue();
+    if (selected_value.isUndefined()) return;
+
+    LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem());
+
+    if (!mPanelPickInfo)
+    {
+        mPanelPickInfo = LLPanelPickInfo::create();
+        mPanelPickInfo->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickInfo));
+        mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelProfilePicks::onPanelPickEdit, this));
+        mPanelPickInfo->setVisible(FALSE);
+    }
+
+    LLSD params;
+    params["pick_id"] = pick->getPickId();
+    params["avatar_id"] = pick->getCreatorId();
+    params["snapshot_id"] = pick->getSnapshotId();
+    params["pick_name"] = pick->getPickName();
+    params["pick_desc"] = pick->getPickDesc();
+
+    getProfilePanel()->openPanel(mPanelPickInfo, params);
+}
+
+// virtual
+void LLPanelProfileLegacy::LLPanelProfilePicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
+{
+    updateButtons();
+
+    auto menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
+    if (menu)
+    {
+        menu->buildDrawLabels();
+        menu->show(x, y);
+        LLMenuGL::showPopup(item, menu, x, y);
+    }
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::openClassifiedInfo()
+{
+    LLSD selected_value = mClassifiedsList->getSelectedValue();
+    if (selected_value.isUndefined()) return;
+
+    LLClassifiedItem* c_item = getSelectedClassifiedItem();
+
+    if (!mPanelClassifiedInfo)
+    {
+        mPanelClassifiedInfo = LLPanelClassifiedInfo::create();
+        mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedClose, this, mPanelClassifiedInfo));
+        mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedEdit, this));
+        mPanelClassifiedInfo->setVisible(FALSE);
+    }
+
+    LLSD params;
+    params["classified_id"] = c_item->getClassifiedId();
+    params["classified_creator_id"] = c_item->getAvatarId();
+    params["classified_snapshot_id"] = c_item->getSnapshotId();
+    params["classified_name"] = c_item->getClassifiedName();
+    params["classified_desc"] = c_item->getDescription();
+    params["from_search"] = false;
+
+    getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
+}
+
+LLClassifiedItem* LLPanelProfileLegacy::LLPanelProfilePicks::getSelectedClassifiedItem() const
+{
+    LLPanel* selected_item = mClassifiedsList->getSelectedItem();
+    if (!selected_item) return nullptr;
+
+    return dynamic_cast<LLClassifiedItem*>(selected_item);
+}
+
+LLPickItem* LLPanelProfileLegacy::LLPanelProfilePicks::getSelectedPickItem() const
+{
+    LLPanel* selected_item = mPicksList->getSelectedItem();
+    if (!selected_item) return nullptr;
+
+    return dynamic_cast<LLPickItem*>(selected_item);
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel)
+{
+    if (!panel->canClose())
+    {
+        return;
+    }
+
+    if (panel->isNew())
+    {
+        mEditClassifiedPanels[panel->getClassifiedId()] = panel;
+
+        LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId());
+        c_item->fillIn(panel);
+
+        LLSD c_value;
+        c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId());
+        c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName());
+        mClassifiedsList->addItem(c_item, c_value, ADD_TOP);
+
+        //c_item->setDoubleClickCallback(boost::bind(&LLPanelProfilePicks::onDoubleClickClassifiedItem, this, _1));
+        c_item->setRightMouseUpCallback(boost::bind(&LLPanelProfilePicks::onRightMouseUpItem, this, _1, _2, _3, _4));
+        c_item->setMouseUpCallback(boost::bind(&LLPanelProfilePicks::updateButtons, this));
+        c_item->childSetAction("info_chevron", boost::bind(&LLPanelProfilePicks::onClickInfo, this));
+
+        // order does matter, showTab will invoke arrange for accordions.
+        //mClassifiedsAccTab->changeOpenClose(false);
+        //showTab("tab_classifieds", true);
+    }
+    else if (panel->isNewWithErrors())
+    {
+        LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
+        llassert(c_item);
+        if (c_item)
+        {
+            c_item->fillIn(panel);
+        }
+    }
+    else
+    {
+        onPanelClassifiedClose(panel);
+        return;
+    }
+
+    onPanelPickClose(panel);
+    updateButtons();
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel)
+{
+    if(panel->getInfoLoaded() && !panel->isDirty())
+    {
+        std::vector<LLSD> values;
+        mClassifiedsList->getValues(values);
+        for (auto& value : values)
+        {
+            LLUUID c_id = value[CLASSIFIED_ID].asUUID();
+            if(panel->getClassifiedId() == c_id)
+            {
+                LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getItemByValue(value));
+                llassert(c_item);
+                if (c_item)
+                {
+                    c_item->setClassifiedName(panel->getClassifiedName());
+                    c_item->setDescription(panel->getDescription());
+                    c_item->setSnapshotId(panel->getSnapshotId());
+                }
+            }
+        }
+    }
+
+    onPanelPickClose(panel);
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onDoubleClickClassifiedItem(LLUICtrl* item)
+{
+    LLSD value = mClassifiedsList->getSelectedValue();
+    if (value.isUndefined()) return;
+
+    LLSD args;
+    args["CLASSIFIED"] = value[CLASSIFIED_NAME];
+    LLNotificationsUtil::add("TeleportToClassified", args, LLSD(),
+        boost::bind(&LLPanelProfilePicks::callbackTeleport, this, _1, _2));
+}
+
+bool LLPanelProfileLegacy::LLPanelProfilePicks::callbackTeleport(const LLSD& notification, const LLSD& response)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+    if (0 == option)
+    {
+        onClickTeleport();
+    }
+    return false;
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickClose(LLPanel* panel)
+{
+    getProfilePanel()->closePanel(panel);
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickSave(LLPanel* panel)
+{
+    getProfilePanel()->closePanel(panel);
+    updateButtons();
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickEditSave(LLPanelPickEdit* panel)
+{
+    panel->sendUpdate();
+    getProfilePanel()->closePanel(panel);
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelEdit()
+{
+    if (getSelectedPickItem())
+    {
+        onPanelPickEdit();
+    }
+    else if (getSelectedClassifiedItem())
+    {
+        onPanelClassifiedEdit();
+    }
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelClassifiedEdit()
+{
+    LLSD selected_value = mClassifiedsList->getSelectedValue();
+    if (selected_value.isUndefined()) return;
+
+    LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
+    llassert(c_item);
+    if (!c_item) return;
+    editClassified(c_item->getClassifiedId());
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::editClassified(const LLUUID& classified_id)
+{
+    LLClassifiedItem* c_item = findClassifiedById(classified_id);
+    if (!c_item)
+    {
+        LL_WARNS() << "item not found for classified_id " << classified_id << LL_ENDL;
+        return;
+    }
+
+    LLSD params;
+    params["classified_id"] = c_item->getClassifiedId();
+    params["classified_creator_id"] = c_item->getAvatarId();
+    params["snapshot_id"] = c_item->getSnapshotId();
+    params["name"] = c_item->getClassifiedName();
+    params["desc"] = c_item->getDescription();
+    params["category"] = (S32)c_item->getCategory();
+    params["content_type"] = (S32)c_item->getContentType();
+    params["auto_renew"] = c_item->getAutoRenew();
+    params["price_for_listing"] = c_item->getPriceForListing();
+    params["location_text"] = c_item->getLocationText();
+
+    LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
+    if (!panel)
+    {
+        createClassifiedEditPanel(&panel);
+        mEditClassifiedPanels[c_item->getClassifiedId()] = panel;
+    }
+    getProfilePanel()->openPanel(panel, params);
+    panel->setPosGlobal(c_item->getPosGlobal());
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onPanelPickEdit()
+{
+    LLSD selected_value = mPicksList->getSelectedValue();
+    if (selected_value.isUndefined()) return;
+
+    LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem());
+
+    LLSD params;
+    params["pick_id"] = pick->getPickId();
+    params["avatar_id"] = pick->getCreatorId();
+    params["snapshot_id"] = pick->getSnapshotId();
+    params["pick_name"] = pick->getPickName();
+    params["pick_desc"] = pick->getPickDesc();
+
+    mPanelPickEdit = LLPanelPickEdit::create();
+    mPanelPickEdit->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit));
+    mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit));
+    mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelProfilePicks::onPanelPickEditSave, this, mPanelPickEdit));
+    getProfilePanel()->openPanel(mPanelPickEdit, params);
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::onPlusMenuItemClicked(const LLSD& param)
+{
+    std::string value = param.asString();
+
+    if ("new_pick" == value)
+    {
+        createNewPick();
+    }
+    else if ("new_classified" == value)
+    {
+        createNewClassified();
+    }
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::createNewPick()
+{
+    createPickEditPanel();
+
+    getProfilePanel()->openPanel(mPanelPickEdit, LLSD());
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::createNewClassified()
+{
+    LLPanelClassifiedEdit* panel = nullptr;
+    createClassifiedEditPanel(&panel);
+
+    getProfilePanel()->openPanel(panel, LLSD());
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::createPickEditPanel()
+{
+    mPanelPickEdit = LLPanelPickEdit::create();
+    mPanelPickEdit->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit));
+    mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelProfilePicks::onPanelPickSave, this, mPanelPickEdit));
+    mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelProfilePicks::onPanelPickClose, this, mPanelPickEdit));
+    mPanelPickEdit->setVisible(FALSE);
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel)
+{
+
+    if (panel)
+    {
+        LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create();
+        new_panel->setExitCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedClose, this, new_panel));
+        new_panel->setSaveCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedSave, this, new_panel));
+        new_panel->setCancelCallback(boost::bind(&LLPanelProfilePicks::onPanelClassifiedClose, this, new_panel));
+        new_panel->setVisible(FALSE);
+        *panel = new_panel;
+    }
+}
+
+bool LLPanelProfileLegacy::LLPanelProfilePicks::isActionEnabled(const LLSD& userdata) const
+{
+    return (!(userdata.asString() == LLStringExplicit("new_pick") && LLAgentPicksInfo::getInstance()->isPickLimitReached()));
+}
+
+void LLPanelProfileLegacy::LLPanelProfilePicks::setProfilePanel(LLPanelProfileLegacy* profile_panel)
+{
+    mProfilePanel = profile_panel;
+}
+
+inline LLPanelProfileLegacy* LLPanelProfileLegacy::LLPanelProfilePicks::getProfilePanel() const
+{
+    llassert_always(mProfilePanel != nullptr);
+    return mProfilePanel;
+}
+
+// LLPanelProfileGroups //
+
+LLPanelProfileLegacy::LLPanelProfileGroups::LLPanelProfileGroups()
+:   LLPanelProfileLegacyTab()
+,   mGroupsText(nullptr)
+,   mGroupsList(nullptr)
+{
+
+}
+
+BOOL LLPanelProfileLegacy::LLPanelProfileGroups::postBuild()
+{
+    mGroupsList = getChild<LLFlatListView>("groups_detail_list");
+    mGroupsText = getChild<LLTextBase>("groups_panel_text");
+    return TRUE;
+}
+
+void LLPanelProfileLegacy::LLPanelProfileGroups::onOpen(const LLSD& key)
+{
+    const LLUUID id(key.asUUID());
+    setAvatarId(id);
+
+    updateData();
+}
+
+void LLPanelProfileLegacy::LLPanelProfileGroups::updateData()
+{
+    mGroupsText->setVisible(TRUE);
+    mGroupsList->clear();
+}
+
+void LLPanelProfileLegacy::LLPanelProfileGroups::processProperties(void* data, EAvatarProcessorType type)
+{
+    if (APT_GROUPS != type) return;
+    const LLAvatarGroups* avatar_groups = static_cast<LLAvatarGroups*>(data);
+    if(!avatar_groups || getAvatarId() != avatar_groups->avatar_id) return;
+
+    for (auto const& gdata: avatar_groups->group_list)
+    {
+        LLProfileGroupItem* item = LLProfileGroupItem::create();
+        item->childSetAction("info_chevron", boost::bind(&LLPanelProfileGroups::showGroup, this, gdata.group_id));
+        item->init(gdata);
+
+        LLSD item_value = LLSD();
+        item_value.insert("group_id", gdata.group_id);
+        item_value.insert("group_name", gdata.group_name);
+        item_value.insert("group_icon", gdata.group_insignia_id);
+        item_value.insert("group_desc", LLStringUtil::null);
+
+        if (!mGroupsList->valueExists(item_value))
+        {
+            mGroupsList->addItem(item, item_value);
+        }
+    }
+}
+
+void LLPanelProfileLegacy::LLPanelProfileGroups::showGroup(const LLUUID& id)
+{
+    LLGroupActions::show(id);
+}
+
+// LLProfileGroupItem //
+
+LLPanelProfileLegacy::LLProfileGroupItem::LLProfileGroupItem()
+:   LLPanel()
+,   mInsignia(LLUUID::null)
+,   mGroupName(LLStringUtil::null)
+,   mCharter(LLStringUtil::null)
+{
+    buildFromFile("panel_profile_legacy_group_list_item.xml");
+}
+
+LLPanelProfileLegacy::LLProfileGroupItem::~LLProfileGroupItem()
+{
+    LLGroupMgr::getInstance()->removeObserver(this);
+}
+
+//static
+LLPanelProfileLegacy::LLProfileGroupItem* LLPanelProfileLegacy::LLProfileGroupItem::create()
+{
+    return new LLProfileGroupItem();
+}
+
+void LLPanelProfileLegacy::LLProfileGroupItem::init(const LLAvatarGroups::LLGroupData& data)
+{
+    setId(data.group_id);
+    setGroupName(data.group_name);
+    setInsignia(data.group_insignia_id);
+    LLGroupMgr::getInstance()->addObserver(this);
+    LLGroupMgr::getInstance()->sendGroupPropertiesRequest(data.group_id);
+
+    LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
+    picture->setImageAssetID(data.group_insignia_id);
+}
+
+BOOL LLPanelProfileLegacy::LLProfileGroupItem::postBuild()
+{
+    setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
+    setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
+    return TRUE;
+}
+
+void LLPanelProfileLegacy::LLProfileGroupItem::setValue(const LLSD& value)
+{
+    if (!value.isMap()) return;;
+    if (!value.has("selected")) return;
+    getChildView("selected_icon")->setVisible( value["selected"]);
+}
+
+void LLPanelProfileLegacy::LLProfileGroupItem::setId(const LLUUID& id)
+{
+    mID = id;
+}
+
+void LLPanelProfileLegacy::LLProfileGroupItem::setInsignia(const LLUUID& id)
+{
+    mInsignia = id;
+    getChild<LLTextureCtrl>("picture")->setImageAssetID(id);
+}
+
+void LLPanelProfileLegacy::LLProfileGroupItem::setGroupName(const std::string& name)
+{
+    mGroupName = name;
+    getChild<LLUICtrl>("name")->setValue(name);
+}
+
+void LLPanelProfileLegacy::LLProfileGroupItem::setCharter(const std::string& charter)
+{
+    mCharter = charter;
+    getChild<LLUICtrl>("description")->setValue(charter);
+}
+
+void LLPanelProfileLegacy::LLProfileGroupItem::changed(LLGroupChange gc)
+{
+    if (gc != GC_PROPERTIES) return;
+    LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID);
+    if (group_data)
+    {
+        setCharter(group_data->mCharter);
+    }
+    LLGroupMgr::getInstance()->removeObserver(this);
+}
+
+// ChildStack //
+
+LLPanelProfileLegacy::ChildStack::ChildStack()
+:   mParent(nullptr)
+{
+}
+
+LLPanelProfileLegacy::ChildStack::~ChildStack()
+{
+    while (!mStack.empty())
+    {
+        view_list_t& top = mStack.back();
+        for (auto viewp : top)
+        {
+            if (viewp)
+            {
+                viewp->die();
+            }
+        }
+        mStack.pop_back();
+    }
+}
+
+void LLPanelProfileLegacy::ChildStack::setParent(LLPanel* parent)
+{
+    llassert_always(parent != nullptr);
+    mParent = parent;
+}
+
+/// Save current parent's child views and remove them from the child list.
+bool LLPanelProfileLegacy::ChildStack::push()
+{
+    view_list_t vlist = *mParent->getChildList();
+
+    for (auto viewp : vlist)
+    {
+        mParent->removeChild(viewp);
+    }
+
+    mStack.push_back(vlist);
+    dump();
+    return true;
+}
+
+/// Restore saved children (adding them back to the child list).
+bool LLPanelProfileLegacy::ChildStack::pop()
+{
+    if (mStack.empty())
+    {
+        LL_WARNS() << "Empty stack" << LL_ENDL;
+        llassert(mStack.size() == 0);
+        return false;
+    }
+
+    view_list_t& top = mStack.back();
+    for (auto viewp : top)
+    {
+        mParent->addChild(viewp);
+    }
+
+    mStack.pop_back();
+    dump();
+    return true;
+}
+
+/// Temporarily add all saved children back.
+void LLPanelProfileLegacy::ChildStack::preParentReshape()
+{
+    mSavedStack = mStack;
+    while(!mStack.empty())
+    {
+        pop();
+    }
+}
+
+/// Add the temporarily saved children back.
+void LLPanelProfileLegacy::ChildStack::postParentReshape()
+{
+    mStack = mSavedStack;
+    mSavedStack = stack_t();
+
+    for (const auto& vlist : mStack)
+    {
+        for (auto viewp : vlist)
+        {
+            LL_DEBUGS() << "removing " << viewp->getName() << LL_ENDL;
+            mParent->removeChild(viewp);
+        }
+    }
+}
+
+void LLPanelProfileLegacy::ChildStack::dump()
+{
+    unsigned lvl = 0;
+    LL_DEBUGS() << "child stack dump:" << LL_ENDL;
+    for (const auto& vlist : mStack)
+    {
+        ++lvl;
+        std::ostringstream dbg_line;
+        dbg_line << "lvl #" << lvl << ":";
+        for (const auto& list_it : vlist)
+        {
+            dbg_line << " " << list_it->getName();
+        }
+        LL_DEBUGS() << dbg_line.str() << LL_ENDL;
+    }
+}
diff --git a/indra/newview/llpanelprofilelegacy.h b/indra/newview/llpanelprofilelegacy.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c30519ab5c49af4e66117e632c30fce82f73a80
--- /dev/null
+++ b/indra/newview/llpanelprofilelegacy.h
@@ -0,0 +1,230 @@
+/*
+ * @file llpanelprofilelegacy.h
+ * @brief Legacy protocol avatar profile panel
+ *
+ * Copyright (c) 2014-2022, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELPROFILELEGACY_H
+#define LL_PANELPROFILELEGACY_H
+
+#include "llgroupmgr.h"
+#include "llpanelavatarlegacy.h"
+
+class LLAvatarName;
+class LLClassifiedItem;
+class LLFlatListView;
+class LLPanel;
+class LLPanelPickEdit;
+class LLPanelPickInfo;
+class LLPanelClassifiedInfo;
+class LLPanelClassifiedEdit;
+class LLPickItem;
+class LLTextBase;
+class LLToggleableMenu;
+
+class LLPanelProfileLegacy final : public LLPanelProfileLegacyTab
+{
+public:
+    LLPanelProfileLegacy();
+    BOOL postBuild() override;
+    void onOpen(const LLSD& key) override;
+    void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
+    void showTab(std::string_view name, bool show) const;
+    LLPanel* expandTab(const std::string& name) const;
+    LLPanel* getExpandedTab() const;
+
+protected:
+    void openPanel(LLPanel* panel, const LLSD& params);
+    void closePanel(LLPanel* panel);
+
+private:
+    ~LLPanelProfileLegacy() override;
+    void updateData() override;
+    void processProperties(void* data, EAvatarProcessorType type) override;
+    void resetControls() override;
+    void resetInterestsControlValues();
+    void setProgress(bool started);
+    void sendAvatarProfileCoro(std::string url, LLSD payload);
+    void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+    void onCommitAvatarProperties();
+    void onCommitInterest();
+    void onCommitNotes(LLUICtrl* ctrl);
+    void onDoubleClickName();
+    void onCommitRights();
+    void onBackBtnClick();
+    void onCommitModifyObjectsRights(LLUICtrl* ctrl);
+    void onCommitAction(const LLSD& userdata);
+    void onNameChanged();
+    bool isActionEnabled(const LLSD& userdata);
+    bool handleConfirmModifyRightsCallback(const LLSD& notification, const LLSD& response);
+    void closeParentFloater();
+
+    boost::signals2::connection mAvatarNameCacheConnection;
+    boost::signals2::connection mNameChangedConnection;
+
+    class ChildStack
+    {
+    public:
+        ChildStack();
+        ~ChildStack();
+        void setParent(LLPanel* parent);
+
+        bool push();
+        bool pop();
+        void preParentReshape();
+        void postParentReshape();
+
+    private:
+        void dump();
+
+        typedef LLView::child_list_t view_list_t;
+        typedef std::list<view_list_t> stack_t;
+
+        stack_t     mStack;
+        stack_t     mSavedStack;
+        LLPanel*    mParent;
+    };
+    ChildStack      mChildStack;
+
+public:
+    class LLPanelProfilePicks final : public LLPanelProfileLegacyTab
+    {
+        friend class LLPanelProfileLegacy;
+    public:
+        LLPanelProfilePicks();
+        ~LLPanelProfilePicks() override;
+        BOOL postBuild() override;
+
+        void createNewPick();
+        void createNewClassified();
+
+    protected:
+        void onOpen(const LLSD& key) override;
+
+    private:
+        void updateData() override;
+        void processProperties(void* data, EAvatarProcessorType type) override;
+        void resetControls() override {};
+        void showAccordion(const std::string& name, bool show);
+        void setProfilePanel(LLPanelProfileLegacy* profile_panel);
+        LLPanelProfileLegacy* getProfilePanel() const;
+        void onPanelPickClose(LLPanel* panel);
+        void onPanelPickSave(LLPanel* panel);
+        void onPanelPickEditSave(LLPanelPickEdit* panel);
+        void onPanelEdit();
+        void onPanelClassifiedEdit();
+        void onPanelPickEdit();
+        void onPlusMenuItemClicked(const LLSD& param);
+        void editClassified(const LLUUID& classified_id);
+        void updateButtons() override;
+        void onClickPlusBtn();
+        void onClickInfo();
+        void onClickTeleport();
+        void onClickShowOnMap();
+        void onClickDelete();
+        void openPickInfo();
+        void openClassifiedInfo();
+        void onPanelClassifiedSave(LLPanelClassifiedEdit* panel);
+        void onPanelClassifiedClose(LLPanelClassifiedInfo* panel);
+        void onDoubleClickClassifiedItem(LLUICtrl* item);
+        LLClassifiedItem* findClassifiedById(const LLUUID& classified_id) const;
+        LLClassifiedItem* getSelectedClassifiedItem() const;
+        LLPickItem* getSelectedPickItem() const;
+
+        void createPickEditPanel();
+        void createClassifiedEditPanel(LLPanelClassifiedEdit** panel);
+
+        bool isActionEnabled(const LLSD& userdata) const;
+        bool callbackDeletePick(const LLSD& notification, const LLSD& response);
+        bool callbackDeleteClassified(const LLSD& notification, const LLSD& response);
+        bool callbackTeleport(const LLSD& notification, const LLSD& response);
+        virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
+
+        LLPanelProfileLegacy* mProfilePanel;
+        LLFlatListView* mClassifiedsList;
+        LLFlatListView* mPicksList;
+        LLPanelPickEdit* mPanelPickEdit;
+        LLPanelPickInfo* mPanelPickInfo;
+        LLPanelClassifiedInfo* mPanelClassifiedInfo;
+        LLHandle<LLView> mPopupMenuHandle;
+        LLHandle<LLToggleableMenu> mPlusMenuHandle;
+
+        // This map is needed for newly created classifieds. The purpose of panel is to
+        // sit in this map and listen to LLPanelClassifiedEdit::processProperties callback.
+        std::map<LLUUID, LLPanelClassifiedEdit*> mEditClassifiedPanels;
+    };
+
+    class LLPanelProfileGroups final : public LLPanelProfileLegacyTab
+    {
+        friend class LLPanelProfileLegacy;
+    public:
+        LLPanelProfileGroups();
+        BOOL postBuild() override;
+
+    protected:
+        void onOpen(const LLSD& key) override;
+
+    private:
+        void updateData() override;
+        void processProperties(void* data, EAvatarProcessorType type) override;
+        void resetControls() override {};
+        void showGroup(const LLUUID& id);
+
+        LLTextBase* mGroupsText;
+        LLFlatListView* mGroupsList;
+    };
+
+    class LLProfileGroupItem final : public LLPanel, public LLGroupMgrObserver
+    {
+      public:
+        LLProfileGroupItem();
+        ~LLProfileGroupItem() override;
+        static LLProfileGroupItem* create();
+        void                       init(const LLAvatarGroups::LLGroupData& data);
+        BOOL                       postBuild() override;
+
+        void setValue(const LLSD& value) override;
+        void setId(const LLUUID& id);
+        void setInsignia(const LLUUID& id);
+        void setGroupName(const std::string& name);
+        void setCharter(const std::string& charter);
+
+      protected:
+        void changed(LLGroupChange gc) override;
+
+      private:
+        LLUUID      mInsignia;
+        std::string mGroupName;
+        std::string mCharter;
+    };
+
+private:
+    LLPanelProfilePicks* mPanelPicks;
+    LLPanelProfileGroups* mPanelGroups;
+};
+
+#endif //LL_PANELPROFILELEGACY_H
diff --git a/indra/newview/llpanelsearchbase.cpp b/indra/newview/llpanelsearchbase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ba11c8a009633eb35b3934992f10d3b599ff794c
--- /dev/null
+++ b/indra/newview/llpanelsearchbase.cpp
@@ -0,0 +1,44 @@
+/*
+ * @file llpanelsearchbase.cpp
+ * @brief Search panel base class
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelsearchbase.h"
+#include "llfloaterdirectory.h"
+
+LLPanelSearch::LLPanelSearch()
+:   LLPanel()
+,   mFloater(nullptr)
+{
+}
+
+void LLPanelSearch::setSearchFloater(LLFloaterDirectory* floater)
+{
+    mFloater = floater;
+}
diff --git a/indra/newview/llpanelsearchbase.h b/indra/newview/llpanelsearchbase.h
new file mode 100644
index 0000000000000000000000000000000000000000..3e54edce0eecb15c3211c92fe04658a8b60e51e5
--- /dev/null
+++ b/indra/newview/llpanelsearchbase.h
@@ -0,0 +1,55 @@
+/*
+ * @file llpanelsearchbase.h
+ * @brief Search panel base class
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELSEARCHBASE_H
+#define LL_PANELSEARCHBASE_H
+
+#include "llpanel.h"
+
+class LLUICtrl;
+class LLFloaterDirectory;
+
+class LLPanelSearch : public LLPanel
+{
+public:
+    LLPanelSearch();
+    BOOL postBuild() override { return FALSE; }
+    void setSearchFloater(LLFloaterDirectory* floater);
+
+protected:
+    virtual ~LLPanelSearch() = default;;
+    LLFloaterDirectory* mFloater;
+
+private:
+    virtual void onCommitSearch(LLUICtrl* ctrl) {}
+    virtual void search() {}
+};
+
+#endif // LL_PANELSEARCHBASE_H
diff --git a/indra/newview/llpanelsearchclassifieds.cpp b/indra/newview/llpanelsearchclassifieds.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4834c63adf11334ab8123ab1cdfeaea90fafb8b5
--- /dev/null
+++ b/indra/newview/llpanelsearchclassifieds.cpp
@@ -0,0 +1,110 @@
+/*
+ * @file llpanelsearchclassifieds.cpp
+ * @brief Groups search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelsearchclassifieds.h"
+#include "llfloaterdirectory.h"
+
+#include "llfloaterreg.h"
+#include "llqueryflags.h"
+#include "lltrans.h"
+
+#include "llagent.h"
+#include "llclassifiedflags.h"
+#include "llclassifiedinfo.h"
+#include "llcombobox.h"
+#include "llnotificationsutil.h"
+#include "llparcel.h"
+#include "llsearcheditor.h"
+#include "llsearchhistory.h"
+
+static LLPanelInjector<LLPanelSearchClassifieds> t_panel_search_classifieds("panel_search_classifieds");
+
+LLPanelSearchClassifieds::LLPanelSearchClassifieds()
+    : LLPanelSearch()
+    , mSearchEditor(nullptr)
+    , mClassifiedsCategory(nullptr)
+{
+    mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchClassifieds::onCommitSearch, this, _1));
+}
+
+BOOL LLPanelSearchClassifieds::postBuild()
+{
+    mClassifiedsCategory = getChild<LLComboBox>("classifieds_category");
+    mClassifiedsCategory->add("All categories", LLSD("any"));
+    mClassifiedsCategory->addSeparator();
+    for (auto iter = LLClassifiedInfo::sCategories.cbegin();
+         iter != LLClassifiedInfo::sCategories.cend();
+         ++iter)
+    {
+        mClassifiedsCategory->add(LLTrans::getString(iter->second));
+    }
+
+    mSearchEditor = getChild<LLSearchEditor>("search_bar");
+    //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchClassifieds::onCommitSearch, this, _1));
+
+    return TRUE;
+}
+
+void LLPanelSearchClassifieds::onCommitSearch(LLUICtrl* ctrl)
+{
+    LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl);
+    if (pSearchEditor)
+    {
+        std::string text = pSearchEditor->getText();
+        LLStringUtil::trim(text);
+        if (text.length() <= MIN_SEARCH_STRING_SIZE)
+            LLSearchHistory::getInstance()->addEntry(text);
+    }
+    search();
+}
+
+void LLPanelSearchClassifieds::search()
+{
+    LLDirQuery query;
+    query.type = SE_CLASSIFIEDS;
+    query.results_per_page = 100;
+    query.text = mSearchEditor->getText();
+    LLStringUtil::trim(query.text);
+
+    query.category_int = mClassifiedsCategory->getValue().asInteger();
+
+    static LLUICachedControl<bool> inc_pg("ShowPGClassifieds", true);
+    static LLUICachedControl<bool> inc_mature("ShowMatureClassifieds", false);
+    static LLUICachedControl<bool> inc_adult("ShowAdultClassifieds", false);
+    if (!(inc_pg || inc_mature || inc_adult))
+    {
+        LLNotificationsUtil::add("NoContentToSearch");
+        return;
+    }
+    query.scope = pack_classified_flags_request(/*auto_renew*/ FALSE, inc_pg, inc_mature, inc_adult);
+
+    mFloater->queryDirectory(query, true);
+}
diff --git a/indra/newview/llpanelsearchclassifieds.h b/indra/newview/llpanelsearchclassifieds.h
new file mode 100644
index 0000000000000000000000000000000000000000..64992be6bb9b2c2592fb914aec7a174c1189bbed
--- /dev/null
+++ b/indra/newview/llpanelsearchclassifieds.h
@@ -0,0 +1,53 @@
+/*
+ * @file llpanelsearchclassifieds.h
+ * @brief Groups search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELSEARCHCLASSIFIEDS_H
+#define LL_PANELSEARCHCLASSIFIEDS_H
+
+#include "llpanelsearchbase.h"
+
+class LLComboBox;
+class LLSearchEditor;
+
+class LLPanelSearchClassifieds : public LLPanelSearch
+{
+public:
+    LLPanelSearchClassifieds();
+    /*virtual*/ BOOL postBuild() override;
+
+private:
+    /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override;
+    /*virtual*/ void search() override;
+
+    LLSearchEditor* mSearchEditor;
+    LLComboBox* mClassifiedsCategory;
+};
+
+#endif // LL_PANELSEARCHCLASSIFIEDS_H
diff --git a/indra/newview/llpanelsearchevents.cpp b/indra/newview/llpanelsearchevents.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..425d5a157bc15fb22657c6bf65b448adf77be190
--- /dev/null
+++ b/indra/newview/llpanelsearchevents.cpp
@@ -0,0 +1,135 @@
+/*
+ * @file llpanelsearchevents.cpp
+ * @brief Events search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelsearchevents.h"
+#include "llfloaterdirectory.h"
+
+#include "llfloaterreg.h"
+#include "llqueryflags.h"
+
+#include "llagent.h"
+#include "llcombobox.h"
+#include "llnotificationsutil.h"
+#include "llparcel.h"
+#include "llsearcheditor.h"
+#include "llsearchhistory.h"
+
+static LLPanelInjector<LLPanelSearchEvents> t_panel_search_events("panel_search_events");
+
+LLPanelSearchEvents::LLPanelSearchEvents()
+:   LLPanelSearch()
+,   mDate(0)
+{
+    mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchEvents::onCommitSearch, this, _1));
+    mCommitCallbackRegistrar.add("Search.AddDay", boost::bind(&LLPanelSearchEvents::addDay, this));
+    mCommitCallbackRegistrar.add("Search.MinusDay", boost::bind(&LLPanelSearchEvents::minusDay, this));
+}
+
+BOOL LLPanelSearchEvents::postBuild()
+{
+    mSearchEditor = getChild<LLSearchEditor>("search_bar");
+    //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchEvents::onCommitSearch, this, _1));
+    setDate(0);
+
+    return TRUE;
+}
+
+void LLPanelSearchEvents::onCommitSearch(LLUICtrl* ctrl)
+{
+    LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl);
+    if (pSearchEditor)
+    {
+        std::string text = pSearchEditor->getText();
+        LLStringUtil::trim(text);
+        if (text.length() <= MIN_SEARCH_STRING_SIZE)
+            LLSearchHistory::getInstance()->addEntry(text);
+    }
+    search();
+}
+
+void LLPanelSearchEvents::search()
+{
+    LLDirQuery query;
+    query.type = SE_EVENTS;
+    query.results_per_page = 200;
+    std::string text = mSearchEditor->getText();
+    LLStringUtil::trim(text);
+
+    static LLUICachedControl<bool> inc_pg("ShowPGEvents", true);
+    static LLUICachedControl<bool> inc_mature("ShowMatureEvents", false);
+    static LLUICachedControl<bool> inc_adult("ShowAdultEvents", false);
+    if (!(inc_pg || inc_mature || inc_adult))
+    {
+        LLNotificationsUtil::add("NoContentToSearch");
+        return;
+    }
+
+    query.scope = DFQ_DATE_EVENTS;
+    if (inc_pg)
+        query.scope |= DFQ_INC_PG;
+    if (inc_mature && gAgent.canAccessMature())
+        query.scope |= DFQ_INC_MATURE;
+    if (inc_adult && gAgent.canAccessAdult())
+        query.scope |= DFQ_INC_ADULT;
+
+    std::ostringstream string;
+    string << (childGetValue("events_search_mode").asString() == "current" ? "u" : llformat("%d",mDate)) << "|"
+           << getChild<LLComboBox>("events_category")->getSelectedValue().asInteger() << "|"
+           << text;
+    query.text = string.str();
+
+    mFloater->queryDirectory(query, true);
+}
+
+void LLPanelSearchEvents::setDate(S32 day)
+{
+    mDate = day;
+
+    time_t utc = time_corrected();
+    utc += day * 24 * 60 * 60;
+    struct tm * internal_time = utc_to_pacific_time(utc, is_daylight_savings());
+    const std::string date = llformat("%d/%d", 1 + internal_time->tm_mon, internal_time->tm_mday);
+    childSetValue("events_date", date);
+}
+
+void LLPanelSearchEvents::addDay()
+{
+    setDate(++mDate);
+    if (childGetValue("events_search_mode").asString() == "date")
+        search();
+}
+
+void LLPanelSearchEvents::minusDay()
+{
+    setDate(--mDate);
+    if (childGetValue("events_search_mode").asString() == "date")
+        search();
+}
diff --git a/indra/newview/llpanelsearchevents.h b/indra/newview/llpanelsearchevents.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f2af30622f89a218e48f4f8dade34e7d512cac8
--- /dev/null
+++ b/indra/newview/llpanelsearchevents.h
@@ -0,0 +1,56 @@
+/*
+ * @file llpanelsearchevents.h
+ * @brief Events search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELSEARCHEVENTS_H
+#define LL_PANELSEARCHEVENTS_H
+
+#include "llpanelsearchbase.h"
+
+class LLComboBox;
+class LLSearchEditor;
+
+class LLPanelSearchEvents : public LLPanelSearch
+{
+public:
+    LLPanelSearchEvents();
+    /*virtual*/ BOOL postBuild() override;
+
+private:
+    /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override;
+    /*virtual*/ void search() override;
+    void setDate(S32 day);
+    void addDay();
+    void minusDay();
+
+    S32 mDate;
+    LLSearchEditor* mSearchEditor;
+};
+
+#endif // LL_PANELSEARCHEVENTS_H
diff --git a/indra/newview/llpanelsearchgroups.cpp b/indra/newview/llpanelsearchgroups.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b4fbea45d86941e09238b746430d9f298a4f814b
--- /dev/null
+++ b/indra/newview/llpanelsearchgroups.cpp
@@ -0,0 +1,99 @@
+/*
+ * @file llpanelsearchgroups.cpp
+ * @brief Groups search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelsearchgroups.h"
+#include "llfloaterdirectory.h"
+
+#include "llfloaterreg.h"
+#include "llqueryflags.h"
+
+#include "llagent.h"
+#include "llnotificationsutil.h"
+#include "llsearcheditor.h"
+#include "llsearchhistory.h"
+
+static LLPanelInjector<LLPanelSearchGroups> t_panel_search_groups("panel_search_groups");
+
+LLPanelSearchGroups::LLPanelSearchGroups()
+    : LLPanelSearch()
+    , mSearchEditor(nullptr)
+{
+    mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchGroups::onCommitSearch, this, _1));
+}
+
+BOOL LLPanelSearchGroups::postBuild()
+{
+    mSearchEditor = getChild<LLSearchEditor>("search_bar");
+    //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchGroups::onCommitSearch, this, _1));
+
+    return TRUE;
+}
+
+void LLPanelSearchGroups::onCommitSearch(LLUICtrl* ctrl)
+{
+    LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl);
+    if (pSearchEditor)
+    {
+        std::string text = pSearchEditor->getText();
+        LLStringUtil::trim(text);
+        if (text.length() <= MIN_SEARCH_STRING_SIZE)
+            LLSearchHistory::getInstance()->addEntry(text);
+    }
+    search();
+}
+
+void LLPanelSearchGroups::search()
+{
+    LLDirQuery query;
+    query.type = SE_GROUPS;
+    query.results_per_page = 100;
+    query.text = mSearchEditor->getText();
+    LLStringUtil::trim(query.text);
+
+    static LLUICachedControl<bool> inc_pg("ShowPGGroups", true);
+    static LLUICachedControl<bool> inc_mature("ShowMatureGroups", false);
+    static LLUICachedControl<bool> inc_adult("ShowAdultGroups", false);
+    if (!(inc_pg || inc_mature || inc_adult))
+    {
+        LLNotificationsUtil::add("NoContentToSearch");
+        return;
+    }
+
+    if (inc_pg)
+        query.scope |= DFQ_INC_PG;
+    if (inc_mature && gAgent.canAccessMature())
+        query.scope |= DFQ_INC_MATURE;
+    if (inc_adult && gAgent.canAccessAdult())
+        query.scope |= DFQ_INC_ADULT;
+    query.scope |= DFQ_GROUPS;
+
+    mFloater->queryDirectory(query, true);
+}
diff --git a/indra/newview/llpanelsearchgroups.h b/indra/newview/llpanelsearchgroups.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3e80c6b17199e4100d3027c3eaf51fea6d76211
--- /dev/null
+++ b/indra/newview/llpanelsearchgroups.h
@@ -0,0 +1,51 @@
+/*
+ * @file llpanelsearchgroups.h
+ * @brief Groups search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELSEARCHGROUPS_H
+#define LL_PANELSEARCHGROUPS_H
+
+#include "llpanelsearchbase.h"
+
+class LLSearchEditor;
+
+class LLPanelSearchGroups : public LLPanelSearch
+{
+public:
+    LLPanelSearchGroups();
+    /*virtual*/ BOOL postBuild() override;
+
+private:
+    /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override;
+    /*virtual*/ void search() override;
+
+    LLSearchEditor* mSearchEditor;
+};
+
+#endif // LL_PANELSEARCHGROUPS_H
diff --git a/indra/newview/llpanelsearchlandsales.cpp b/indra/newview/llpanelsearchlandsales.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a2def0f36a6c16948d3eded04e9183eec5fb2fd7
--- /dev/null
+++ b/indra/newview/llpanelsearchlandsales.cpp
@@ -0,0 +1,118 @@
+/*
+ * @file llpanelsearchlandsales.cpp
+ * @brief Groups search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelsearchlandsales.h"
+#include "llfloaterdirectory.h"
+
+#include "llfloaterreg.h"
+#include "llqueryflags.h"
+
+#include "llagent.h"
+#include "llnotificationsutil.h"
+#include "llsearcheditor.h"
+#include "llsearchhistory.h"
+#include "llviewercontrol.h"
+
+static LLPanelInjector<LLPanelSearchLandSales> t_panel_search_land_sales("panel_search_landsales");
+
+LLPanelSearchLandSales::LLPanelSearchLandSales()
+:   LLPanelSearch()
+{
+    mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchLandSales::onCommitSearch, this, _1));
+}
+
+BOOL LLPanelSearchLandSales::postBuild()
+{
+    return TRUE;
+}
+
+void LLPanelSearchLandSales::onCommitSearch(LLUICtrl* ctrl)
+{
+    search();
+}
+
+void LLPanelSearchLandSales::search()
+{
+    LLDirQuery query;
+    query.type = SE_LANDSALES;
+    query.results_per_page = 100;
+
+    static LLUICachedControl<bool> inc_pg("ShowPGLand", true);
+    static LLUICachedControl<bool> inc_mature("ShowMatureLand", false);
+    static LLUICachedControl<bool> inc_adult("ShowAdultLand", false);
+    static LLUICachedControl<bool> limit_price("FindLandPrice", true);
+    static LLUICachedControl<bool> limit_area("FindLandArea", true);
+    if (!(inc_pg || inc_mature || inc_adult))
+    {
+        LLNotificationsUtil::add("NoContentToSearch");
+        return;
+    }
+
+    const std::string& type = gSavedSettings.getString("FindLandType");
+    if (type == "All")
+        query.category_int = ST_ALL;
+    else if (type == "Auction")
+        query.category_int = ST_AUCTION;
+    else if (type == "Mainland")
+        query.category_int = ST_MAINLAND;
+    else if (type == "Estate")
+        query.category_int = ST_ESTATE;
+
+    if (gAgent.wantsPGOnly())
+        query.scope |= DFQ_PG_SIMS_ONLY;
+    if (inc_pg)
+        query.scope |= DFQ_INC_PG;
+    if (inc_mature && gAgent.canAccessMature())
+        query.scope |= DFQ_INC_MATURE;
+    if (inc_adult && gAgent.canAccessAdult())
+        query.scope |= DFQ_INC_ADULT;
+
+    const std::string& sort = gSavedSettings.getString("FindLandSort");
+    if (sort == "Name")
+        query.scope |= DFQ_NAME_SORT;
+    else if (sort == "Price")
+        query.scope |= DFQ_PRICE_SORT;
+    else if (sort == "PPM")
+        query.scope |= DFQ_PER_METER_SORT;
+    else if (sort == "Area")
+        query.scope |= DFQ_AREA_SORT;
+
+    if (gSavedSettings.getBOOL("FindLandSortAscending"))
+        query.scope |= DFQ_SORT_ASC;
+    if (limit_price)
+        query.scope |= DFQ_LIMIT_BY_PRICE;
+    if (limit_area)
+        query.scope |= DFQ_LIMIT_BY_AREA;
+    query.price = childGetValue("edit_price").asInteger();
+    query.area = childGetValue("edit_area").asInteger();
+
+    mFloater->queryDirectory(query, true);
+}
diff --git a/indra/newview/llpanelsearchlandsales.h b/indra/newview/llpanelsearchlandsales.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0f27407719333b67bef0b86b3aa344a2a81eb78
--- /dev/null
+++ b/indra/newview/llpanelsearchlandsales.h
@@ -0,0 +1,47 @@
+/*
+ * @file llpanelsearchlandsales.h
+ * @brief Land sale search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELSEARCHLANDSALES_H
+#define LL_PANELSEARCHLANDSALES_H
+
+#include "llpanelsearchbase.h"
+
+class LLPanelSearchLandSales : public LLPanelSearch
+{
+public:
+    LLPanelSearchLandSales();
+    /*virtual*/ BOOL postBuild() override;
+
+private:
+    /*virtual*/ void search() override;
+    /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override;
+};
+
+#endif // LL_PANELSEARCHLANDSALES_H
diff --git a/indra/newview/llpanelsearchpeople.cpp b/indra/newview/llpanelsearchpeople.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..69b2c3fc5c4adee9059322d7f1918538187cef5b
--- /dev/null
+++ b/indra/newview/llpanelsearchpeople.cpp
@@ -0,0 +1,87 @@
+/*
+ * @file llpanelsearchpeople.cpp
+ * @brief People search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelsearchpeople.h"
+#include "llfloaterdirectory.h"
+
+#include "llfloaterreg.h"
+
+#include "llagent.h"
+#include "llsearcheditor.h"
+#include "llsearchhistory.h"
+
+static LLPanelInjector<LLPanelSearchPeople> t_panel_search_people("panel_search_people");
+
+LLPanelSearchPeople::LLPanelSearchPeople()
+:   LLPanelSearch()
+{
+    mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchPeople::onCommitSearch, this, _1));
+}
+
+BOOL LLPanelSearchPeople::postBuild()
+{
+    mSearchEditor = getChild<LLSearchEditor>("search_bar");
+    //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchPeople::onCommitSearch, this, _1));
+
+    return TRUE;
+}
+
+void LLPanelSearchPeople::onCommitSearch(LLUICtrl* ctrl)
+{
+    LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl);
+    if (pSearchEditor)
+    {
+        std::string text = pSearchEditor->getText();
+        LLStringUtil::trim(text);
+        if (text.length() <= MIN_SEARCH_STRING_SIZE)
+            LLSearchHistory::getInstance()->addEntry(text);
+    }
+    search();
+}
+
+bool isNotAlphaNum(char c)
+{
+    return !std::isalnum(c);
+}
+
+void LLPanelSearchPeople::search()
+{
+    LLDirQuery query;
+    query.type = SE_PEOPLE;
+    query.results_per_page = 100;
+    query.text = mSearchEditor->getText();
+    std::replace_if(query.text.begin(), query.text.end(), isNotAlphaNum, ' ');
+    LLStringUtil::trim(query.text);
+
+    mFloater->queryDirectory(query, true);
+    if (query.text.length() < MIN_SEARCH_STRING_SIZE)
+        mFloater->setResultsComment(getString("SeachFilteredOnShortWordsEmpty"));
+}
diff --git a/indra/newview/llpanelsearchpeople.h b/indra/newview/llpanelsearchpeople.h
new file mode 100644
index 0000000000000000000000000000000000000000..e55645f7f626ae438f99d23aeecc6a6231ba3ba2
--- /dev/null
+++ b/indra/newview/llpanelsearchpeople.h
@@ -0,0 +1,51 @@
+/*
+ * @file llpanelsearchpeople.h
+ * @brief People search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELSEARCHPEOPLE_H
+#define LL_PANELSEARCHPEOPLE_H
+
+#include "llpanelsearchbase.h"
+
+class LLSearchEditor;
+
+class LLPanelSearchPeople : public LLPanelSearch
+{
+public:
+    LLPanelSearchPeople();
+    /*virtual*/ BOOL postBuild() override;
+
+private:
+    /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override;
+    /*virtual*/ void search() override;
+
+    LLSearchEditor* mSearchEditor;
+};
+
+#endif // LL_PANELSEARCHPEOPLE_H
diff --git a/indra/newview/llpanelsearchplaces.cpp b/indra/newview/llpanelsearchplaces.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..97b758dea427417cf47cc10236ba509af28f1630
--- /dev/null
+++ b/indra/newview/llpanelsearchplaces.cpp
@@ -0,0 +1,113 @@
+/*
+ * @file llpanelsearchplaces.cpp
+ * @brief Groups search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelsearchplaces.h"
+#include "llfloaterdirectory.h"
+
+#include "llfloaterreg.h"
+#include "llqueryflags.h"
+
+#include "llagent.h"
+#include "llcombobox.h"
+#include "llnotificationsutil.h"
+#include "llparcel.h"
+#include "llsearcheditor.h"
+#include "llsearchhistory.h"
+
+static LLPanelInjector<LLPanelSearchPlaces> t_panel_search_places("panel_search_places");
+
+LLPanelSearchPlaces::LLPanelSearchPlaces()
+:   LLPanelSearch()
+{
+    mCommitCallbackRegistrar.add("Search.query", boost::bind(&LLPanelSearchPlaces::onCommitSearch, this, _1));
+}
+
+BOOL LLPanelSearchPlaces::postBuild()
+{
+    mPlacesCategory = getChild<LLComboBox>("places_category");
+    mPlacesCategory->add("All categories", LLSD("any"));
+    mPlacesCategory->addSeparator();
+    for (size_t category = LLParcel::C_LINDEN; category < LLParcel::C_COUNT; ++category)
+    {
+        LLParcel::ECategory eCategory = static_cast<LLParcel::ECategory>(category);
+        mPlacesCategory->add(LLParcel::getCategoryUIString(eCategory), LLParcel::getCategoryString(eCategory));
+    }
+
+    mSearchEditor = getChild<LLSearchEditor>("search_bar");
+    //mSearchEditor->setKeystrokeCallback(boost::bind(&LLPanelSearchPlaces::onCommitSearch, this, _1));
+
+    return TRUE;
+}
+
+void LLPanelSearchPlaces::onCommitSearch(LLUICtrl* ctrl)
+{
+    LLSearchEditor* pSearchEditor = dynamic_cast<LLSearchEditor*>(ctrl);
+    if (pSearchEditor)
+    {
+        std::string text = pSearchEditor->getText();
+        LLStringUtil::trim(text);
+        if (text.length() <= MIN_SEARCH_STRING_SIZE)
+            LLSearchHistory::getInstance()->addEntry(text);
+    }
+    search();
+}
+
+void LLPanelSearchPlaces::search()
+{
+    LLDirQuery query;
+    query.type = SE_PLACES;
+    query.results_per_page = 100;
+    query.text = mSearchEditor->getText();
+    LLStringUtil::trim(query.text);
+
+    const std::string& category_string = mPlacesCategory->getSelectedValue();
+    query.category_char = category_string == "any" ? LLParcel::C_ANY : LLParcel::getCategoryFromString(category_string);
+
+    static LLUICachedControl<bool> inc_pg("ShowPGSims", true);
+    static LLUICachedControl<bool> inc_mature("ShowMatureSims", false);
+    static LLUICachedControl<bool> inc_adult("ShowAdultSims", false);
+    if (!(inc_pg || inc_mature || inc_adult))
+    {
+        LLNotificationsUtil::add("NoContentToSearch");
+        return;
+    }
+    if (gAgent.wantsPGOnly())
+        query.scope |= DFQ_PG_SIMS_ONLY;
+    if (inc_pg)
+        query.scope |= DFQ_INC_PG;
+    if (inc_mature && gAgent.canAccessMature())
+        query.scope |= DFQ_INC_MATURE;
+    if (inc_adult && gAgent.canAccessAdult())
+        query.scope |= DFQ_INC_ADULT;
+    query.scope |= DFQ_DWELL_SORT;
+
+    mFloater->queryDirectory(query, true);
+}
diff --git a/indra/newview/llpanelsearchplaces.h b/indra/newview/llpanelsearchplaces.h
new file mode 100644
index 0000000000000000000000000000000000000000..42e69dd117da94b2a3a9c876d4073563d2dca396
--- /dev/null
+++ b/indra/newview/llpanelsearchplaces.h
@@ -0,0 +1,53 @@
+/*
+ * @file llpanelsearchplaces.h
+ * @brief Groups search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELSEARCHPLACES_H
+#define LL_PANELSEARCHPLACES_H
+
+#include "llpanelsearchbase.h"
+
+class LLComboBox;
+class LLSearchEditor;
+
+class LLPanelSearchPlaces : public LLPanelSearch
+{
+public:
+    LLPanelSearchPlaces();
+    /*virtual*/ BOOL postBuild() override;
+
+private:
+    /*virtual*/ void onCommitSearch(LLUICtrl* ctrl) override;
+    /*virtual*/ void search() override;
+
+    LLSearchEditor* mSearchEditor;
+    LLComboBox* mPlacesCategory;
+};
+
+#endif // LL_PANELSEARCHPLACES_H
diff --git a/indra/newview/llpanelsearchweb.cpp b/indra/newview/llpanelsearchweb.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dfd9fedc3efe90eb78d412ddfe9e9463383df564
--- /dev/null
+++ b/indra/newview/llpanelsearchweb.cpp
@@ -0,0 +1,281 @@
+/*
+ * @file llpanelsearchweb.cpp
+ * @brief Web search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelsearchweb.h"
+
+#include "llagent.h"
+#include "llfloaterdirectory.h"
+#include "lllogininstance.h"
+#include "llmediactrl.h"
+#include "llprogressbar.h"
+#include "lltextbox.h"
+#include "llviewercontrol.h"
+#include "llviewernetwork.h"
+#include "llviewerregion.h"
+#include "llweb.h"
+
+static LLPanelInjector<LLPanelSearchWeb> t_panel_search_web("panel_search_web");
+
+LLPanelSearchWeb::LLPanelSearchWeb()
+:   LLPanel()
+,   mStatusBarText(nullptr)
+,   mStatusBarProgress(nullptr)
+,   mBtnBack(nullptr)
+,   mBtnForward(nullptr)
+,   mBtnReload(nullptr)
+,   mBtnStop(nullptr)
+,   mWebBrowser(nullptr)
+{
+    mSearchType.insert("standard");
+    mSearchType.insert("land");
+    mSearchType.insert("classified");
+
+    mCollectionType.insert("events");
+    mCollectionType.insert("destinations");
+    mCollectionType.insert("places");
+    mCollectionType.insert("groups");
+    mCollectionType.insert("people");
+
+    mCategoryPaths = LLSD::emptyMap();
+    mCategoryPaths["all"] = "search";
+    mCategoryPaths["people"] = "search/people";
+    mCategoryPaths["places"] = "search/places";
+    mCategoryPaths["events"] = "search/events";
+    mCategoryPaths["groups"] = "search/groups";
+    mCategoryPaths["wiki"] = "search/wiki";
+    mCategoryPaths["destinations"] = "destinations";
+
+    mCommitCallbackRegistrar.add("WebContent.Back", boost::bind(&LLPanelSearchWeb::onClickBack, this));
+    mCommitCallbackRegistrar.add("WebContent.Forward", boost::bind(&LLPanelSearchWeb::onClickForward, this));
+    mCommitCallbackRegistrar.add("WebContent.Reload", boost::bind(&LLPanelSearchWeb::onClickReload, this));
+    mCommitCallbackRegistrar.add("WebContent.Stop", boost::bind(&LLPanelSearchWeb::onClickStop, this));
+}
+
+BOOL LLPanelSearchWeb::postBuild()
+{
+    mWebBrowser = getChild<LLMediaCtrl>("webbrowser");
+    if (mWebBrowser) mWebBrowser->addObserver(this);
+
+    mWebBrowser        = getChild<LLMediaCtrl>("webbrowser");
+    mStatusBarProgress = getChild<LLProgressBar>("statusbarprogress");
+    mStatusBarText     = getChild<LLTextBox>("statusbartext");
+
+    mBtnBack           = getChild<LLButton>("back");
+    mBtnForward        = getChild<LLButton>("forward");
+    mBtnReload         = getChild<LLButton>("reload");
+    mBtnStop           = getChild<LLButton>("stop");
+
+    return TRUE;
+}
+
+void LLPanelSearchWeb::loadUrl(const SearchQuery& p)
+{
+    if (!mWebBrowser || !p.validateBlock()) return;
+
+    mWebBrowser->setTrustedContent(true);
+
+    // work out the subdir to use based on the requested category
+    LLSD subs;
+    if (LLGridManager::instance().isInSecondlife())
+    {
+        if (mSearchType.find(p.category.getValue()) != mSearchType.end())
+        {
+            subs["TYPE"] = p.category.getValue();
+        }
+        else
+        {
+            subs["TYPE"] = "standard";
+        }
+
+        subs["COLLECTION"] = "";
+        if (subs["TYPE"] == "standard")
+        {
+            if (mCollectionType.find(p.collection) != mCollectionType.end())
+            {
+                subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection);
+            }
+            else
+            {
+                std::string collection_args("");
+                for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it)
+                {
+                    collection_args += "&collection_chosen=" + std::string(*it);
+                }
+                subs["COLLECTION"] = collection_args;
+            }
+        }
+    }
+    else
+    {
+        subs["CATEGORY"] = (mCategoryPaths.has(p.category.getValue())
+            ? mCategoryPaths[p.category.getValue()].asString()
+            : mCategoryPaths["all"].asString());
+    }
+
+    // add the search query string
+    subs["QUERY"] = LLURI::escape(p.query());
+
+    // add the user's preferred maturity (can be changed via prefs)
+    std::string maturity;
+    if (LLGridManager::instance().isInSecondlife())
+    {
+        if (gAgent.prefersAdult())
+        {
+            maturity = "gma";  // PG,Mature,Adult
+        }
+        else if (gAgent.prefersMature())
+        {
+            maturity = "gm";  // PG,Mature
+        }
+        else
+        {
+            maturity = "g";  // PG
+        }
+    }
+    else
+    {
+        if (gAgent.prefersAdult())
+        {
+            maturity = "42";  // PG,Mature,Adult
+        }
+        else if (gAgent.prefersMature())
+        {
+            maturity = "21";  // PG,Mature
+        }
+        else
+        {
+            maturity = "13";  // PG
+        }
+    }
+    subs["MATURITY"] = maturity;
+
+    // add the user's god status
+    subs["GODLIKE"] = gAgent.isGodlike() ? "1" : "0";
+
+    // Get the search URL and expand all of the substitutions
+    // (also adds things like [LANGUAGE], [VERSION], [OS], etc.)
+    LLViewerRegion* regionp = gAgent.getRegion();
+    std::string url = regionp != nullptr ? regionp->getSearchServerURL()
+        : gSavedSettings.getString(LLGridManager::getInstance()->isInOpenSim() ? "OpenSimSearchURL" : "SearchURL");
+    url = LLWeb::expandURLSubstitutions(url, subs);
+    // Finally, load the URL in the webpanel
+    mWebBrowser->navigateTo(url, "text/html");
+}
+
+// virtual
+void LLPanelSearchWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+    if(event == MEDIA_EVENT_LOCATION_CHANGED)
+    {
+        const std::string url = self->getLocation();
+
+        if ( url.length() )
+            mStatusBarText->setText( url );
+    }
+    else if(event == MEDIA_EVENT_NAVIGATE_BEGIN)
+    {
+        // flags are sent with this event
+        mBtnBack->setEnabled( self->getHistoryBackAvailable() );
+        mBtnForward->setEnabled( self->getHistoryForwardAvailable() );
+
+        // toggle visibility of these buttons based on browser state
+        mBtnReload->setVisible( false );
+        mBtnStop->setVisible( true );
+
+        // turn "on" progress bar now we're about to start loading
+        mStatusBarProgress->setVisible( true );
+    }
+    else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
+    {
+        // flags are sent with this event
+        mBtnBack->setEnabled( self->getHistoryBackAvailable() );
+        mBtnForward->setEnabled( self->getHistoryForwardAvailable() );
+
+        // toggle visibility of these buttons based on browser state
+        mBtnReload->setVisible( true );
+        mBtnStop->setVisible( false );
+
+        // turn "off" progress bar now we're loaded
+        mStatusBarProgress->setVisible( false );
+
+        // we populate the status bar with URLs as they change so clear it now we're done
+        const LLStringExplicit end_str("");
+        mStatusBarText->setText( end_str );
+    }
+    else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED )
+    {
+        const std::string text = self->getStatusText();
+        if ( text.length() )
+            mStatusBarText->setText( text );
+    }
+    else if(event == MEDIA_EVENT_PROGRESS_UPDATED )
+    {
+        int percent = (int)self->getProgressPercent();
+        mStatusBarProgress->setValue( percent );
+    }
+    else if(event == MEDIA_EVENT_LINK_HOVERED )
+    {
+        const std::string link = self->getHoverLink();
+        mStatusBarText->setText( link );
+    }
+}
+
+void LLPanelSearchWeb::onClickForward() const
+{
+    mWebBrowser->navigateForward();
+}
+
+void LLPanelSearchWeb::onClickBack() const
+{
+    mWebBrowser->navigateBack();
+}
+
+void LLPanelSearchWeb::onClickReload() const
+{
+
+    if( mWebBrowser->getMediaPlugin() )
+    {
+        bool ignore_cache = true;
+        mWebBrowser->getMediaPlugin()->browse_reload( ignore_cache );
+    }
+}
+
+void LLPanelSearchWeb::onClickStop()
+{
+    if( mWebBrowser->getMediaPlugin() )
+        mWebBrowser->getMediaPlugin()->browse_stop();
+
+    // still should happen when we catch the navigate complete event
+    // but sometimes (don't know why) that event isn't sent from Qt
+    // and we ghetto a point where the stop button stays active.
+    mBtnReload->setVisible( true );
+    mBtnStop->setVisible( false );
+}
diff --git a/indra/newview/llpanelsearchweb.h b/indra/newview/llpanelsearchweb.h
new file mode 100644
index 0000000000000000000000000000000000000000..4877db8bf962381301582b9606d8740674e26647
--- /dev/null
+++ b/indra/newview/llpanelsearchweb.h
@@ -0,0 +1,70 @@
+/*
+ * @file llpanelsearchweb.h
+ * @brief Web search panel
+ *
+ * Copyright (c) 2014, Cinder Roxley <cinder@sdf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef LL_PANELSEARCHWEB_H
+#define LL_PANELSEARCHWEB_H
+
+#include "llpanel.h"
+#include "llviewermediaobserver.h"
+
+class LLMediaCtrl;
+class LLProgressBar;
+class LLTextBox;
+struct SearchQuery;
+
+class LLPanelSearchWeb : public LLPanel, public LLViewerMediaObserver
+{
+public:
+    LLPanelSearchWeb();
+    BOOL postBuild() override;
+    void loadUrl(const SearchQuery& query);
+
+private:
+    void             onClickBack() const;
+    void             onClickForward() const;
+    void             onClickReload() const;
+    void             onClickStop();
+    /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
+
+    LLTextBox* mStatusBarText;
+    LLProgressBar* mStatusBarProgress;
+    LLButton* mBtnBack;
+    LLButton* mBtnForward;
+    LLButton* mBtnReload;
+    LLButton* mBtnStop;
+
+    std::set<std::string> mSearchType;
+    std::set<std::string> mCollectionType;
+    LLSD mCategoryPaths;
+    //U8 mSearchGodLevel;
+    LLMediaCtrl* mWebBrowser;
+};
+
+#endif // LL_PANELSEARCHWEB_H
diff --git a/indra/newview/llpickitem.cpp b/indra/newview/llpickitem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..55e59d125511a65783fd9d62e3c044931af89a26
--- /dev/null
+++ b/indra/newview/llpickitem.cpp
@@ -0,0 +1,155 @@
+/**
+* @file llpickitem.cpp
+* @brief Widget
+*
+* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llpickitem.h"
+
+#include "lltexturectrl.h"
+
+LLPickItem::LLPickItem()
+    : LLPanel()
+    , mPickID(LLUUID::null)
+    , mCreatorID(LLUUID::null)
+    , mParcelID(LLUUID::null)
+    , mSnapshotID(LLUUID::null)
+    , mNeedData(true)
+{
+    buildFromFile("panel_pick_list_item.xml");
+}
+
+LLPickItem::~LLPickItem()
+{
+    if (mCreatorID.notNull())
+    {
+        LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
+    }
+
+}
+
+LLPickItem* LLPickItem::create()
+{
+    return new LLPickItem();
+}
+
+void LLPickItem::init(LLPickData* pick_data)
+{
+    setPickDesc(pick_data->desc);
+    setSnapshotId(pick_data->snapshot_id);
+    mPosGlobal = pick_data->pos_global;
+    mSimName = pick_data->sim_name;
+    mPickDescription = pick_data->desc;
+    mUserName = pick_data->user_name;
+    mOriginalName = pick_data->original_name;
+
+    LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
+    picture->setImageAssetID(pick_data->snapshot_id);
+}
+
+void LLPickItem::setPickName(const std::string& name)
+{
+    mPickName = name;
+    getChild<LLUICtrl>("picture_name")->setValue(name);
+
+}
+
+const std::string& LLPickItem::getPickName() const
+{
+    return mPickName;
+}
+
+const LLUUID& LLPickItem::getCreatorId() const
+{
+    return mCreatorID;
+}
+
+const LLUUID& LLPickItem::getSnapshotId() const
+{
+    return mSnapshotID;
+}
+
+void LLPickItem::setPickDesc(const std::string& descr)
+{
+    getChild<LLUICtrl>("picture_descr")->setValue(descr);
+}
+
+void LLPickItem::setPickId(const LLUUID& id)
+{
+    mPickID = id;
+}
+
+const LLUUID& LLPickItem::getPickId() const
+{
+    return mPickID;
+}
+
+const LLVector3d& LLPickItem::getPosGlobal() const
+{
+    return mPosGlobal;
+}
+
+const std::string LLPickItem::getDescription() const
+{
+    return getChild<LLUICtrl>("picture_descr")->getValue().asString();
+}
+
+void LLPickItem::update()
+{
+    setNeedData(true);
+    LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID);
+}
+
+void LLPickItem::processProperties(void *data, EAvatarProcessorType type)
+{
+    if (APT_PICK_INFO != type)
+    {
+        return;
+    }
+
+    LLPickData* pick_data = static_cast<LLPickData *>(data);
+    if (!pick_data || mPickID != pick_data->pick_id)
+    {
+        return;
+    }
+
+    init(pick_data);
+    setNeedData(false);
+    LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
+}
+
+BOOL LLPickItem::postBuild()
+{
+    setMouseEnterCallback(std::bind(&set_child_visible, this, "hovered_icon", true));
+    setMouseLeaveCallback(std::bind(&set_child_visible, this, "hovered_icon", false));
+    return TRUE;
+}
+
+void LLPickItem::setValue(const LLSD& value)
+{
+    if (!value.isMap()) return;;
+    if (!value.has("selected")) return;
+    getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
diff --git a/indra/newview/llpickitem.h b/indra/newview/llpickitem.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ddcbd4bf86490c4e1d176e3ddae09e92c768a62
--- /dev/null
+++ b/indra/newview/llpickitem.h
@@ -0,0 +1,85 @@
+/**
+* @file llpickitem.h
+* @brief Widget
+*
+* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_PICKITEM_H
+#define LL_PICKITEM_H
+
+#include "llavatarpropertiesprocessor.h"
+#include "llpanel.h"
+
+struct LLPickData;
+
+static const std::string PICK_ID("pick_id");
+static const std::string PICK_CREATOR_ID("pick_creator_id");
+static const std::string PICK_NAME("pick_name");
+
+class LLPickItem final : public LLPanel, public LLAvatarPropertiesObserver
+{
+public:
+    LLPickItem();
+    ~LLPickItem();
+    BOOL postBuild() override;
+
+    static LLPickItem* create();
+    void init(LLPickData* pick_data);
+    void setPickName(const std::string& name);
+    void setPickDesc(const std::string& descr);
+    void setPickId(const LLUUID& id);
+    void setCreatorId(const LLUUID& id) { mCreatorID = id; };
+    void setSnapshotId(const LLUUID& id) { mSnapshotID = id; };
+    void setNeedData(bool need) { mNeedData = need; };
+    const LLUUID& getPickId() const;
+    const std::string& getPickName() const;
+    const LLUUID& getCreatorId() const;
+    const LLUUID& getSnapshotId() const;
+    const LLVector3d& getPosGlobal() const;
+    const std::string getDescription() const;
+    const std::string& getSimName() const { return mSimName; }
+    const std::string& getUserName() const { return mUserName; }
+    const std::string& getOriginalName() const { return mOriginalName; }
+    const std::string& getPickDesc() const { return mPickDescription; }
+    void processProperties(void* data, EAvatarProcessorType type) override;
+    void update();
+
+    /** setting on/off background icon to indicate selected state */
+    void setValue(const LLSD& value) override;
+
+protected:
+    LLUUID mPickID;
+    LLUUID mCreatorID;
+    LLUUID mParcelID;
+    LLUUID mSnapshotID;
+    LLVector3d mPosGlobal;
+    bool mNeedData;
+
+    std::string mPickName;
+    std::string mUserName;
+    std::string mOriginalName;
+    std::string mPickDescription;
+    std::string mSimName;
+};
+
+#endif // LL_PICKITEM_H
diff --git a/indra/newview/llprofileimagepicker.cpp b/indra/newview/llprofileimagepicker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9930b6eea7818ef444207f8cac038dd888bcf372
--- /dev/null
+++ b/indra/newview/llprofileimagepicker.cpp
@@ -0,0 +1,233 @@
+/**
+* @file llprofileimagepicker.cpp
+* @brief Specialized profile image filepicker
+*
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2022, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llprofileimagepicker.h"
+
+#include "llavatariconctrl.h"
+#include "llagent.h"
+#include "llloadingindicator.h"
+#include "llnotificationsutil.h"
+#include "llpanel.h"
+#include "llviewertexturelist.h"
+
+static constexpr std::string_view PROFILE_IMAGE_UPLOAD_CAP("UploadAgentProfileImage");
+
+static void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image,
+    LLProfileImagePicker::ugly_picker_cb_t cb);
+static LLUUID post_profile_image(std::string cap_url, const LLSD& first_data, std::string path_to_image);
+static void setImageUploading(LLPanel* panel, bool loading);
+
+
+LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel>* handle, ugly_picker_cb_t const& cb)
+:   LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE)
+,   mHandle(handle)
+,   mType(type),
+    mCallback(cb)
+{ }
+
+LLProfileImagePicker::~LLProfileImagePicker()
+{
+    delete mHandle;
+}
+
+void LLProfileImagePicker::notify(const std::vector<std::string>& filenames)
+{
+    if (mHandle->isDead())
+    {
+        return;
+    }
+    if (filenames.empty())
+    {
+        return;
+    }
+    const std::string& file_path = filenames.at(0);
+    if (file_path.empty())
+    {
+        return;
+    }
+
+    // generate a temp texture file for coroutine
+    std::string const& temp_file = gDirUtilp->getTempFilename();
+    U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path));
+    const S32 MAX_DIM = 256;
+    if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM))
+    {
+        LLSD notif_args;
+        notif_args["REASON"] = LLImage::getLastThreadError().c_str();
+        LLNotificationsUtil::add("CannotUploadTexture", notif_args);
+        LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL;
+        return;
+    }
+
+    std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
+    if (cap_url.empty())
+    {
+        LLSD args;
+        args["CAPABILITY"] = std::string(PROFILE_IMAGE_UPLOAD_CAP);
+        LLNotificationsUtil::add("RegionCapabilityRequestError", args);
+        LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL;
+        return;
+    }
+
+    setImageUploading(mHandle->get(), true);
+    LLCoros::instance().launch("postAgentUserImageCoro",
+                               [cap_url, this, temp_file]
+                               {
+                                   return post_profile_image_coro(cap_url, mType, temp_file, mCallback);
+                               });
+}
+
+LLUUID post_profile_image(std::string cap_url, const LLSD& first_data, std::string path_to_image)
+{
+    LLCore::HttpRequest::policy_t               httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
+        new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpHeaders::ptr_t httpHeaders;
+
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+    httpOpts->setFollowRedirects(true);
+
+    LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
+
+    LLSD               httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status      = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+    // todo: notification?
+    LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
+    return LLUUID::null;
+    }
+    if (!result.has("uploader"))
+    {
+    // todo: notification?
+    LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
+    return LLUUID::null;
+    }
+    std::string uploader_cap = result["uploader"].asString();
+    if (uploader_cap.empty())
+    {
+    LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
+    return LLUUID::null;
+    }
+
+    // Upload the image
+
+    LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest);
+    LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders);
+    LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions);
+    S64                        length;
+
+    {
+    llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
+    if (!instream.is_open())
+    {
+        LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+        return LLUUID::null;
+    }
+    length = instream.tellg();
+    }
+
+    uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2");         // optional
+    uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length));  // required!
+    uploaderhttpOpts->setFollowRedirects(true);
+
+    result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
+
+    httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    status      = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    LL_WARNS("AvatarProperties") << result << LL_ENDL;
+
+    if (!status)
+    {
+    LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL;
+    return LLUUID::null;
+    }
+
+    if (result["state"].asString() != "complete")
+    {
+    if (result.has("message"))
+    {
+        LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
+    }
+    else
+    {
+        LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL;
+    }
+    return LLUUID::null;
+    }
+
+    return result["new_asset"].asUUID();
+}
+
+void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image,
+                             LLProfileImagePicker::ugly_picker_cb_t cb)
+{
+    LLSD data;
+    switch (type)
+    {
+    case PROFILE_IMAGE_SL:
+        data["profile-image-asset"] = "sl_image_id";
+        break;
+    case PROFILE_IMAGE_FL:
+        data["profile-image-asset"] = "fl_image_id";
+        break;
+    }
+
+    LLUUID result = post_profile_image(cap_url, data, path_to_image);
+
+    cb(result);
+
+    if (type == PROFILE_IMAGE_SL && result.notNull())
+    {
+        LLAvatarIconIDCache::getInstance()->add(gAgentID, result);
+        // Should trigger callbacks in icon controls
+        LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID);
+    }
+
+    // Cleanup
+    LLFile::remove(path_to_image);
+}
+
+void setImageUploading(LLPanel* panel, bool loading)
+{
+    LLLoadingIndicator* indicator = panel->findChild<LLLoadingIndicator>("image_upload_indicator");
+    if (indicator)
+    {
+        indicator->setVisible(loading);
+        if (loading)
+        {
+            indicator->start();
+        }
+        else
+        {
+            indicator->stop();
+        }
+    }
+}
diff --git a/indra/newview/llprofileimagepicker.h b/indra/newview/llprofileimagepicker.h
new file mode 100644
index 0000000000000000000000000000000000000000..a67d0859b08efd4fbc6fb85f39f876ad215c28e3
--- /dev/null
+++ b/indra/newview/llprofileimagepicker.h
@@ -0,0 +1,53 @@
+/**
+* @file llprofileimagepicker.h
+* @brief Specialized profile image filepicker
+*
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2022, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_PROFILEIMAGEPICKER_H
+#define LL_PROFILEIMAGEPICKER_H
+
+#include "llviewermenufile.h"
+
+enum EProfileImageType
+{
+    PROFILE_IMAGE_SL,
+    PROFILE_IMAGE_FL,
+};
+
+class LLProfileImagePicker final : public LLFilePickerThread
+{
+public:
+    typedef std::function<void(LLUUID const&)> ugly_picker_cb_t;
+
+    LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel>* handle, ugly_picker_cb_t const& cb);
+    ~LLProfileImagePicker() override;
+    void notify(const std::vector<std::string>& filenames) override;
+
+private:
+    LLHandle<LLPanel>* mHandle;
+    EProfileImageType mType;
+    ugly_picker_cb_t mCallback;
+};
+
+#endif //  LL_PROFILEIMAGEPICKER_H
diff --git a/indra/newview/llsearchcombobox.h b/indra/newview/llsearchcombobox.h
index 891237e92eae314003f39c58d728f32d2b12887f..ff9c74a6a84736edd863b78a9a26ec18ee80a74d 100644
--- a/indra/newview/llsearchcombobox.h
+++ b/indra/newview/llsearchcombobox.h
@@ -61,11 +61,6 @@ class LLSearchComboBox : public LLComboBox
 
     ~LLSearchComboBox();
 
-    /**
-     * Sets focus to text box
-     */
-    void focusTextEntry();
-
 protected:
 
     LLSearchComboBox(const Params&p);
@@ -98,6 +93,11 @@ class LLSearchComboBox : public LLComboBox
      */
     void onSelectionCommit();
 
+    /**
+     * Sets focus to text box
+     */
+    void focusTextEntry();
+
     LLButton* mSearchButton;
 };
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index f4fe10b4b128f43abcdc04942ee2d4e120c9aa74..5650732f72f5d44bedfbcadfdb109ef10b548db4 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -183,6 +183,7 @@
 #include "pipeline.h"
 #include "llappviewer.h"
 #include "llfasttimerview.h"
+#include "llfloaterdirectory.h"
 #include "llfloatermap.h"
 #include "llweb.h"
 #include "llvoiceclient.h"
@@ -220,7 +221,6 @@
 #if LL_WINDOWS
 #include "lldxhardware.h"
 #endif
-#include "fsfloatersearch.h"
 
 //
 // exported globals
@@ -2914,12 +2914,13 @@ void register_viewer_callbacks(LLMessageSystem* msg)
     msg->setHandlerFuncFast(_PREHASH_GroupNoticesListReply, LLPanelGroupNotices::processGroupNoticesListReply);
 
     // directory search
-    msg->setHandlerFuncFast(_PREHASH_DirPeopleReply, FSPanelSearchPeople::processSearchReply);
-    msg->setHandlerFuncFast(_PREHASH_DirPlacesReply, FSPanelSearchPlaces::processSearchReply);
-    msg->setHandlerFuncFast(_PREHASH_DirGroupsReply, FSPanelSearchGroups::processSearchReply);
-    msg->setHandlerFuncFast(_PREHASH_DirEventsReply, FSPanelSearchEvents::processSearchReply);
-    msg->setHandlerFuncFast(_PREHASH_DirLandReply,   FSPanelSearchLand::processSearchReply);
-    msg->setHandlerFuncFast(_PREHASH_DirClassifiedReply,  FSPanelSearchClassifieds::processSearchReply);
+    msg->setHandlerFunc("DirPeopleReply", LLFloaterDirectory::processSearchPeopleReply);
+    msg->setHandlerFunc("DirGroupsReply", LLFloaterDirectory::processSearchGroupsReply);
+    msg->setHandlerFunc("DirPlacesReply", LLFloaterDirectory::processSearchPlacesReply);
+    msg->setHandlerFunc("DirEventsReply", LLFloaterDirectory::processSearchEventsReply);
+    msg->setHandlerFunc("DirLandReply",   LLFloaterDirectory::processSearchLandReply);
+    msg->setHandlerFunc("DirClassifiedReply",  LLFloaterDirectory::processSearchClassifiedsReply);
+
 
     msg->setHandlerFuncFast(_PREHASH_AvatarPickerReply, LLFloaterAvatarPicker::processAvatarPickerReply);
 
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index a3d70aa4ffe01495ecf1c8a30b82e3cf2c9b46c0..721717e68adfa21af6ad1b6e37a82736c14b5d64 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -83,6 +83,7 @@
 #include "llfloatercreatelandmark.h"
 #include "llfloaterdeleteprefpreset.h"
 #include "llfloaterdestinations.h"
+#include "llfloaterdirectory.h"
 #include "llfloaterdisplayname.h"
 #include "llfloatereditextdaycycle.h"
 #include "llfloateremojipicker.h"
@@ -144,7 +145,9 @@
 #include "llfloaterpreferenceviewadvanced.h"
 #include "llfloaterpreviewtrash.h"
 #include "llfloaterprofile.h"
+#include "llfloaterprofilelegacy.h"
 #include "llfloaterprogressview.h"
+#include "llfloaterpublishclassified.h"
 #include "llfloaterregiondebugconsole.h"
 #include "llfloaterregioninfo.h"
 #include "llfloaterregionrestarting.h"
@@ -192,7 +195,6 @@
 #include "llmoveview.h"
 #include "llfloaterimnearbychat.h"
 #include "llpanelblockedlist.h"
-#include "llpanelprofileclassifieds.h"
 #include "llpanelemojicomplete.h"
 #include "llpreviewanim.h"
 #include "llpreviewgesture.h"
@@ -202,12 +204,12 @@
 #include "llpreviewtexture.h"
 #include "llscriptfloater.h"
 #include "llsyswellwindow.h"
-#include "fsfloatersearch.h"
 #include "bdfloaterposer.h"
 #include "bdfloaterposecreator.h"
 
 // *NOTE: Please add files in alphabetical order to keep merges easy.
 // [RLVa:KB] - Checked: 2010-03-11
+#include "llfloaterwebprofile.h"
 #include "rlvfloaters.h"
 // [/RLVa:KB]
 // handle secondlife:///app/openfloater/{NAME} URLs
@@ -499,7 +501,7 @@ void LLViewerFloaterReg::registerFloaters()
     LLFloaterReg::add("preview_sound", "floater_preview_sound.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewSound>, "preview");
     LLFloaterReg::add("preview_texture", "floater_preview_texture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewTexture>, "preview");
     LLFloaterReg::add("preview_trash", "floater_preview_trash.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreviewTrash>);
-    LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPublishClassifiedFloater>);
+    LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPublishClassified>);
     LLFloaterReg::add("save_pref_preset", "floater_save_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSavePrefPreset>);
     LLFloaterReg::add("save_camera_preset", "floater_save_camera_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSaveCameraPreset>);
     LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);
@@ -543,7 +545,6 @@ void LLViewerFloaterReg::registerFloaters()
     LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
     LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
     LLFloaterReg::add("simple_snapshot", "floater_simple_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleSnapshot>);
-    LLFloaterReg::add("search", "floater_fs_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterSearch>);
     //LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
 // [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-26 (Catznip-2.3)
     LLFloaterReg::add("search_replace", "floater_search_replace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearchReplace>);
@@ -576,6 +577,7 @@ void LLViewerFloaterReg::registerFloaters()
     LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteQueue>);
     LLFloaterReg::add("generic_text", "floater_generic_text.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGenericText>);
     LLFloaterReg::add("group_profile", "floater_group_profile.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupProfile>);
+    LLFloaterReg::add("legacy_profile", "floater_profile_legacy.xml", (LLFloaterBuildFunc) &LLFloaterReg::build<LLFloaterProfileLegacy>);
     LLFloaterReg::add("lightbox", "floater_lightbox_settings.xml", (LLFloaterBuildFunc) &LLFloaterReg::build<ALFloaterLightBox>);
     LLFloaterReg::add("message_builder", "floater_message_builder.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMessageBuilder>);
     LLFloaterReg::add("message_log", "floater_message_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMessageLog>);
@@ -588,8 +590,11 @@ void LLViewerFloaterReg::registerFloaters()
     LLFloaterReg::add("progress_view", "floater_progress_view.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProgressView>);
     LLFloaterReg::add("quick_settings", "floater_quick_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
     LLFloaterReg::add("region_tracker", "floater_region_tracker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterRegionTracker>);
+    LLFloaterReg::add("search", "floater_directory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDirectory>);
     LLFloaterReg::add("settings_color", "floater_settings_color.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterSettingsColor>);
     LLFloaterReg::add("sound_explorer", "floater_explore_sounds.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterExploreSounds>);
+    LLFloaterReg::add("webprofile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
+
 
     LLFloaterReg::registerControlVariables(); // Make sure visibility and rect controls get preserved when saving
 }
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
index 74e8c10132132aa4c721b5270955f0ac26996735..9639fb38ed4598cd48052f743ff499743e739427 100644
--- a/indra/newview/llviewerinput.cpp
+++ b/indra/newview/llviewerinput.cpp
@@ -49,7 +49,6 @@
 #include "llfloatercamera.h"
 #include "llinitparam.h"
 #include "llselectmgr.h"
-#include "fsfloatersearch.h"
 #include "llfloaterwebcontent.h"
 // [RLVa:KB] - Checked: 2021-07-29 (RLVa-1.4.4a)
 #include "rlvactions.h"
@@ -709,7 +708,7 @@ bool start_chat( EKeystate s )
 bool start_gesture( EKeystate s )
 {
     LLFloater* focused_floater = gFloaterView->getFocusedFloater();
-    if (focused_floater && (dynamic_cast<LLFloaterWebContent*>(focused_floater) || dynamic_cast<FSFloaterSearch*>(focused_floater)))
+    if (focused_floater && dynamic_cast<LLFloaterWebContent*>(focused_floater))
     {
         return true;
     }
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index adceae2d1913841e39afa1129da1f0e39a3e7bce..91c3df6f3145db7296683810e1989c28c0a3e73d 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3895,7 +3895,7 @@ void handle_avatar_eject(const LLSD& avatar_id)
 
 bool my_profile_visible()
 {
-    LLFloater* floaterp = LLAvatarActions::getProfileFloater(gAgentID);
+    LLFloater* floaterp = LLAvatarActions::findProfileFloater(gAgentID);
     return floaterp && floaterp->isInVisibleChain();
 }
 
@@ -6770,7 +6770,7 @@ class LLAvatarToggleMyProfile : public view_listener_t
 {
     bool handleEvent(const LLSD& userdata)
     {
-        LLFloater* instance = LLAvatarActions::getProfileFloater(gAgent.getID());
+        LLFloater* instance = LLAvatarActions::findProfileFloater(gAgent.getID());
         if (LLFloater::isMinimized(instance))
         {
             instance->setMinimized(FALSE);
@@ -6796,7 +6796,7 @@ class LLAvatarTogglePicks : public view_listener_t
 {
     bool handleEvent(const LLSD& userdata)
     {
-        LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID());
+        LLFloater * instance = LLAvatarActions::findProfileFloater(gAgent.getID());
         if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome()))
         {
             instance->setMinimized(FALSE);
diff --git a/indra/newview/skins/alchemy/colors.xml b/indra/newview/skins/alchemy/colors.xml
index ac16fb8113a959ea9f16f43749ef701ca0596209..fd72faa3f24bde3049adec7f70f701ab56dce829 100644
--- a/indra/newview/skins/alchemy/colors.xml
+++ b/indra/newview/skins/alchemy/colors.xml
@@ -1139,6 +1139,9 @@
   <color
    name="StatBarMeanBarColor"
    reference="Red_80" />
+  <color
+   name="ProfileOnlineIndicatorColor"
+   reference="Green" />
   <color
    name="FriendChatColor"
    reference="White" />
diff --git a/indra/newview/skins/alchemy/skin_settings.xml b/indra/newview/skins/alchemy/skin_settings.xml
index 03ac8fb0eca54393fbbea459181a0de586e45e0e..1f56287b50d1684ef534e7fe8e54126780c124c1 100644
--- a/indra/newview/skins/alchemy/skin_settings.xml
+++ b/indra/newview/skins/alchemy/skin_settings.xml
@@ -1,7 +1,20 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="llsd.xsd">
 	<map>
+		<key>LegacyProfile</key>
+		<map>
+			<key>Comment</key>
+			<string>Use Legacy Profiles rather than standard</string>
+			<key>Persist</key>
+			<integer>0</integer>
+			<key>HideFromEditor</key>
+			<integer>1</integer>
+			<key>Type</key>
+			<string>Boolean</string>
+			<key>Value</key>
+			<boolean>0</boolean>
+		</map>
 		<key>LegacyNotificationWell</key>
 		<map>
 			<key>Comment</key>
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index db03b869897bc89ec65ff828e3d71b3ca9d17f1e..c93686df3d9614c09e2718798c353f3f0ac2856a 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -1039,7 +1039,11 @@
       name="PanelNotificationListItem"
       value="0.3 0.3 0.3 .3" />
 
-	<!-- profiles -->
+	<color
+	 name="ProfileOnlineIndicatorColor"
+	 reference="Green" />
+
+	<!-- dildo profiles -->
     <color
         name="StatusUserOnline"
         reference="White" />
diff --git a/indra/newview/skins/default/skin_settings.xml b/indra/newview/skins/default/skin_settings.xml
index 03ac8fb0eca54393fbbea459181a0de586e45e0e..1f56287b50d1684ef534e7fe8e54126780c124c1 100644
--- a/indra/newview/skins/default/skin_settings.xml
+++ b/indra/newview/skins/default/skin_settings.xml
@@ -1,7 +1,20 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="llsd.xsd">
 	<map>
+		<key>LegacyProfile</key>
+		<map>
+			<key>Comment</key>
+			<string>Use Legacy Profiles rather than standard</string>
+			<key>Persist</key>
+			<integer>0</integer>
+			<key>HideFromEditor</key>
+			<integer>1</integer>
+			<key>Type</key>
+			<string>Boolean</string>
+			<key>Value</key>
+			<boolean>0</boolean>
+		</map>
 		<key>LegacyNotificationWell</key>
 		<map>
 			<key>Comment</key>
diff --git a/indra/newview/skins/default/textures/icon_legacy_event.tga b/indra/newview/skins/default/textures/icon_legacy_event.tga
deleted file mode 100644
index 7805dbce60eb7c58bb99826157ed222813c27419..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icon_legacy_event.tga and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icon_legacy_event_adult.tga b/indra/newview/skins/default/textures/icon_legacy_event_adult.tga
deleted file mode 100644
index c344fb1e78887afe2b20ac4830ffb057772416cd..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icon_legacy_event_adult.tga and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icon_legacy_event_mature.tga b/indra/newview/skins/default/textures/icon_legacy_event_mature.tga
deleted file mode 100644
index 61c879bc923c7d1ee625a3995012a3ddecca363d..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icon_legacy_event_mature.tga and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_1.png b/indra/newview/skins/default/textures/icons/ProgressLarge_1.png
deleted file mode 100644
index ff277fc431d6d5f8b13baeb47b478f321e00ab79..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_1.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_10.png b/indra/newview/skins/default/textures/icons/ProgressLarge_10.png
deleted file mode 100644
index 1c94e21d89261478fdde301cf1309dcc3bbe3065..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_10.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_11.png b/indra/newview/skins/default/textures/icons/ProgressLarge_11.png
deleted file mode 100644
index 89bea9b474bbbdb36be8e1024c00d226a22070f9..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_11.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_12.png b/indra/newview/skins/default/textures/icons/ProgressLarge_12.png
deleted file mode 100644
index da38475ba4dc61dfe4bff14a3175837f07d13fa3..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_12.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_2.png b/indra/newview/skins/default/textures/icons/ProgressLarge_2.png
deleted file mode 100644
index c024275ebef799760ab3ae4f1ef9377df066632e..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_2.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_3.png b/indra/newview/skins/default/textures/icons/ProgressLarge_3.png
deleted file mode 100644
index 87b931e72e753c263fc0f07bddd2448ce123d8be..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_3.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_4.png b/indra/newview/skins/default/textures/icons/ProgressLarge_4.png
deleted file mode 100644
index 6dbef74361edb829542a2809fb2a976f03008cac..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_4.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_5.png b/indra/newview/skins/default/textures/icons/ProgressLarge_5.png
deleted file mode 100644
index daccf9b375ffc677a02aa434bd0fc2514c1d614b..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_5.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_6.png b/indra/newview/skins/default/textures/icons/ProgressLarge_6.png
deleted file mode 100644
index cafddcb88dc21d60592ca403c46fd7fc0289adb9..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_6.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_7.png b/indra/newview/skins/default/textures/icons/ProgressLarge_7.png
deleted file mode 100644
index 8acf6472d4d70d6fb758fa7321584c8bf7c6e621..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_7.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_8.png b/indra/newview/skins/default/textures/icons/ProgressLarge_8.png
deleted file mode 100644
index df0e825cef1f053d42c4fffca7efdd0e9f4969cf..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_8.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_9.png b/indra/newview/skins/default/textures/icons/ProgressLarge_9.png
deleted file mode 100644
index 293a7b8f5c6c7983e2e46c56cb661a1994ad3249..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/icons/ProgressLarge_9.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index c80f637a649b24200d318154bcd5306ddb58f0f2..ec2de431bae5834b7499e475bc302fe50cc515b4 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -990,21 +990,4 @@ with the same filename but different name
   <texture name="Right_Trigger" file_name="xbox/right_trigger.png" preload="false" />
   <texture name="Triggers" file_name="xbox/triggers.png" preload="false" />
   <texture name="None" file_name="xbox/none.png" preload="false" />
-  
-  <texture name="Icon_Legacy_Event_PG" file_name="icon_legacy_event.tga" preload="false" />
-  <texture name="Icon_Legacy_Event_Mature" file_name="icon_legacy_event_mature.tga" preload="false" />
-  <texture name="Icon_Legacy_Event_Adult" file_name="icon_legacy_event_adult.tga" preload="false" />
-
-  <texture name="ProgressLarge_1" file_name="icons/ProgressLarge_1.png" preload="true" />
-  <texture name="ProgressLarge_2" file_name="icons/ProgressLarge_2.png" preload="true" />
-  <texture name="ProgressLarge_3" file_name="icons/ProgressLarge_3.png" preload="true" />
-  <texture name="ProgressLarge_4" file_name="icons/ProgressLarge_4.png" preload="true" />
-  <texture name="ProgressLarge_5" file_name="icons/ProgressLarge_5.png" preload="true" />
-  <texture name="ProgressLarge_6" file_name="icons/ProgressLarge_6.png" preload="true" />
-  <texture name="ProgressLarge_7" file_name="icons/ProgressLarge_7.png" preload="true" />
-  <texture name="ProgressLarge_8" file_name="icons/ProgressLarge_8.png" preload="true" />
-  <texture name="ProgressLarge_9" file_name="icons/ProgressLarge_9.png" preload="true" />
-  <texture name="ProgressLarge_10" file_name="icons/ProgressLarge_10.png" preload="true" />
-  <texture name="ProgressLarge_11" file_name="icons/ProgressLarge_11.png" preload="true" />
-  <texture name="ProgressLarge_12" file_name="icons/ProgressLarge_12.png" preload="true" />
 </textures>
diff --git a/indra/newview/skins/default/xui/en/floater_directory.xml b/indra/newview/skins/default/xui/en/floater_directory.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3c6d0cb7fee1f17c5a061f15982c43aef2957e74
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_directory.xml
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ single_instance="true"
+ can_resize="true"
+ height="590"
+ min_height="135"
+ min_width="430"
+ layout="topleft"
+ name="search"
+ save_rect="true"
+ title="SEARCH"
+ width="602">
+  <floater.string
+   name="not_found">
+&apos;[TEXT]&apos; not found
+  </floater.string>
+  <floater.string
+   name="no_results">
+No results
+  </floater.string>
+  <floater.string
+   name="result_spillover">
+Over [TOTAL] results Showing [VISIBLE_BEGIN]/[VISIBLE_END]
+  </floater.string>
+  <floater.string
+   name="result_count">
+[TOTAL] results.
+  </floater.string>
+  <floater.string
+   name="searching">
+Searching...
+  </floater.string>
+  <floater.string
+   name="all_categories">
+All Categories
+  </floater.string>
+  <floater.string
+   name="search_banned">
+Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards.
+  </floater.string>
+  <floater.string
+   name="search_short">
+Your search terms were too short so no search was performed.
+  </floater.string>
+  <floater.string
+   name="search_disabled">
+Directory search is disabled in this region.
+  </floater.string>
+  <floater.string
+   name="search_no_date_offset">
+Your search terms were missing the date offset.
+  </floater.string>
+  <floater.string
+   name="search_no_catgory">
+Your search terms were missing a category.
+  </floater.string>
+  <floater.string
+   name="search_no_query">
+Your search terms were missing a query string.
+  </floater.string>
+  <tab_container
+   border="true"
+   follows="all"
+   top="16"
+   left="0"
+   height="573"
+   width="602"
+   name="search_tabs"
+   tab_min_width="70"
+   tab_position="top">
+    <panel
+     border="false"
+     label="People"
+     filename="panel_search_people.xml"
+     class="panel_search_people"
+     name="panel_search_people"
+     follows="left|top|right"
+     layout="topleft"
+     left="0"
+     top="0"
+     bottom="-16" />
+    <panel
+     border="false"
+     label="Groups"
+     filename="panel_search_groups.xml"
+     class="panel_search_groups"
+     name="panel_search_groups"
+     follows="left|top|right"
+     layout="topleft"
+     left="0"
+     top="0"
+     bottom="-1" />
+    <panel
+     border="false"
+     label="Places"
+     filename="panel_search_places.xml"
+     class="panel_search_places"
+     name="panel_search_places"
+     follows="left|top|right"
+     layout="topleft"
+     left="0"
+     top="0"
+     bottom="-1" />
+    <panel
+     border="false"
+     label="Land"
+     filename="panel_search_landsales.xml"
+     class="panel_search_landsales"
+     name="panel_search_landsales"
+     follows="left|top|right"
+     layout="topleft"
+     left="0"
+     top="0"
+     bottom="-1" />
+    <panel
+     border="false"
+     label="Events"
+     filename="panel_search_events.xml"
+     class="panel_search_events"
+     name="panel_search_events"
+     follows="left|top|right"
+     layout="topleft"
+     left="0"
+     top="0"
+     bottom="-1" />
+    <panel
+     border="false"
+     label="Classifieds"
+     filename="panel_search_classifieds.xml"
+     class="panel_search_classifieds"
+     name="panel_search_classifieds"
+     follows="left|top|right"
+     layout="topleft"
+     left="0"
+     top="0"
+     bottom="-1" />
+    <panel
+     border="false"
+     label="AltaVista"
+     filename="panel_search_web.xml"
+     class="panel_search_web"
+     name="panel_search_web"
+     follows="all"
+     layout="topleft"
+     left="0"
+     top="0"
+     bottom="-1" />
+  </tab_container>
+ <layout_stack
+  follows="all"
+  animate="false"
+  top="86"
+  height="480"
+  left="0"
+  right="-1"
+  drag_handle_gap="2"
+  drag_handle_first_indent="1"
+  drag_handle_second_indent="1"
+  layout="topleft"
+  name="results_stack"
+  orientation="horizontal"
+  show_drag_handle="true">
+   <layout_panel
+    border="true"
+    auto_resize="true"
+    user_resize="true"
+    layout="topleft"
+    top="0"
+    left="0"
+    width="300"
+    bottom="-1"
+    min_height="10"
+    name="results_lp">
+     <scroll_list
+      layout="topleft"
+      top="1"
+      left="2"
+      width="300"
+      bottom="-1"
+      column_padding="0"
+      draw_heading="true"
+      follows="left|right|top|bottom"
+      multi_select="true"
+      name="results"
+      search_column="0" />
+   </layout_panel>
+   <layout_panel
+    border="true"
+    auto_resize="true"
+    user_resize="true"
+    layout="topleft"
+    top="0"
+    bottom="-1"
+    left="405"
+    width="313"
+    min_height="10"
+    name="detail_lp">
+     <panel
+      follows="all"
+      name="detail_avatar"
+      top="0"
+      bottom="-1"
+      left="0"
+      width="313"
+      class="panel_profile_legacy_sidetray"
+      filename="panel_profile_legacy_sidetray.xml" />
+     <panel
+      follows="all"
+      name="detail_group"
+      top="0"
+      bottom="-1"
+      left="0"
+      width="313"
+      class="panel_group_info_sidetray"
+      filename="panel_group_info_sidetray.xml" />
+     <panel
+      follows="all"
+      name="detail_place"
+      top="0"
+      bottom="-1"
+      left="0"
+      width="313"
+      class="panel_places"
+      filename="panel_places.xml" />
+     <panel
+      follows="all"
+      name="detail_event"
+      top="0"
+      bottom="-1"
+      left="0"
+      width="313"
+      class="panel_event_info"
+     filename="panel_event_info.xml" />
+     <panel
+      follows="all"
+      name="detail_classified"
+      top="0"
+      bottom="-1"
+      left="0"
+      width="313"
+      class="panel_classified_info"
+      filename="panel_classified_info.xml" />
+   </layout_panel>
+ </layout_stack>
+ <text
+  follows="bottom|left"
+  height="16"
+  layout="topleft"
+  left="4"
+  name="results_status"
+  top_pad="3"
+  value="[TOTAL] results"
+  width="205" />
+ <button
+  follows="bottom|left"
+  height="16"
+  width="16"
+  image_unselected="Arrow_Left"
+  image_disabled="Arrow_Left_Off"
+  image_disabled_selected="Arrow_Left_Off"
+  image_selected="Arrow_Left"
+  image_pressed="Arrow_Left"
+  image_top_pad="0"
+  layout="topleft"
+  left_pad="5"
+  name="PageDn"
+  top_delta="0" />
+ <button
+  follows="bottom|left"
+  height="16"
+  width="16"
+  image_unselected="Arrow_Right"
+  image_disabled="Arrow_Right_Off"
+  image_disabled_selected="Arrow_Right_Off"
+  image_selected="Arrow_Right"
+  image_pressed="Arrow_Right"
+  image_top_pad="0"
+  layout="topleft"
+  left_pad="5"
+  name="PageUp"
+  top_delta="0" />
+ <loading_indicator
+  follows="bottom|right"
+  height="16"
+  layout="topleft"
+  right="-4"
+  name="loading"
+  top_delta="0"
+  width="16" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_event.xml b/indra/newview/skins/default/xui/en/floater_event.xml
index 67eb4931e1be41fde99b944bec80f77a0c2eb551..4b430877762bd213bc1f664b670dc7e612a8c98c 100644
--- a/indra/newview/skins/default/xui/en/floater_event.xml
+++ b/indra/newview/skins/default/xui/en/floater_event.xml
@@ -1,39 +1,23 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <floater
- height="400"
+ height="590"
  can_resize="true"
  help_topic="event_details"
  label="Event"
  layout="topleft"
  name="Event"
- save_rect="true"
  save_visibility="false"
- title="EVENT DETAILS" 
- width="600">
-	<floater.string
-		name="loading_text">
-		Loading...
-	</floater.string>
-    <floater.string
-     name="done_text">
-        Done
-    </floater.string>
-  <web_browser
-     trusted_content="true" 
-     follows="left|right|top|bottom"
-     layout="topleft"
-     left="10"
-     name="browser"
-     height="365"
-     width="580"
-     top="0"/>
-	<text
-	 follows="bottom|left"
-	 height="16"
-	 layout="topleft"
-	 left_delta="0"
-	 name="status_text"
-	 top_pad="10"
-	 width="150" />	 
+ title="EVENT DETAILS"
+ max_width="320"
+ width="313">
+  <panel
+   follows="all"
+   name="event_panel"
+   top="0"
+   bottom="590"
+   left="0"
+   right="313"
+   class="panel_event_info"
+   filename="panel_event_info.xml" />
 </floater>
 
diff --git a/indra/newview/skins/default/xui/en/floater_fs_search.xml b/indra/newview/skins/default/xui/en/floater_fs_search.xml
deleted file mode 100644
index 67e9d1630db9bec66acf70ce9ae02adabb9c0408..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/floater_fs_search.xml
+++ /dev/null
@@ -1,337 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
-	can_resize="true"
-	default_tab_group="1"
-	height="590"
-	help_topic="search"
-	layout="topleft"
-	legacy_header_height="0"
-	min_height="590"
-	min_width="660"
-	name="floater_search"
-	positioning="centered"
-	save_rect="true"
-	single_instance="true"
-	title="SEARCH"
-	width="780">
-	<!-- Strings -->
-	<floater.string name="string.location">
-		Location: [LOCATION]
-	</floater.string>
-	<floater.string name="string.traffic">
-		Traffic: [DWELL]
-	</floater.string>
-	<floater.string name="string.area">
-		Area: [AREA]
-	</floater.string>
-	<floater.string name="string.members">
-		Members: [MEMBER_COUNT]
-	</floater.string>
-	<floater.string name="string.founder">
-		Founder: [FOUNDER]
-	</floater.string>
-	<floater.string name="string.age">
-		Age: [AGE]
-	</floater.string>
-	<floater.string name="string.partner">
-		Partner: [PARTNER]
-	</floater.string>
-	<floater.string name="string.listing_price">
-		Listing Price: [LISTING_PRICE]
-	</floater.string>
-	<floater.string name="string.slurl">
-		[SLURL]
-	</floater.string>
-	<floater.string name="string.duration">
-		Duration: [DURATION]
-	</floater.string>
-	<floater.string name="string.covercharge">
-		Cover: [COVERCHARGE]
-	</floater.string>
-	<!-- Tab time -->
-	<tab_container
-		layout="topleft"
-		follows="all"
-		top="1"
-		left="0"
-		name="ls_tabs"
-		tab_min_width="90"
-		tab_position="top"
-		width="780"
-		height="585">
-		<panel
-			class="panel_ls_web"
-			filename="panel_fs_search_legacy_web.xml"
-			label="Websearch"
-			layout="topleft"
-			name="panel_ls_web" />
-		<panel
-			class="panel_ls_people"
-			filename="panel_fs_search_legacy_people.xml"
-			label="People"
-			layout="topleft"
-			name="panel_ls_people" />
-		<panel
-			class="panel_ls_groups"
-			filename="panel_fs_search_legacy_groups.xml"
-			label="Groups"
-			layout="topleft"
-			name="panel_ls_groups" />
-		<panel
-			class="panel_ls_places"
-			filename="panel_fs_search_legacy_places.xml"
-			label="Places"
-			layout="topleft"
-			name="panel_ls_places" />
-		<panel
-			class="panel_ls_land"
-			filename="panel_fs_search_legacy_land.xml"
-			label="Land Sales"
-			layout="topleft"
-			name="panel_ls_land" />
-		<panel
-			class="panel_ls_events"
-			filename="panel_fs_search_legacy_events.xml"
-			label="Events"
-			layout="topleft"
-			name="panel_ls_events" />
-		<panel
-			class="panel_ls_classifieds"
-			filename="panel_fs_search_legacy_classifieds.xml"
-			label="Classifieds"
-			layout="topleft"
-			name="panel_ls_classifieds" />
-	</tab_container>
-	<!-- Details/Action Panes -->
-	<panel
-		border="true"
-		follows="top|right|bottom"
-		height="508"
-		layout="topleft"
-		left="412"
-		top="80"
-		width="366"
-		name="panel_ls_details">
-		<text_editor
-		left="12"
-		top="5"
-		height="24"
-		width="340"
-		layout="topleft"
-		follows="left|top|right"
-		name="title"
-		bg_visible="false"
-		border_visible="false"
-		allow_scroll="false"
-		h_pad="0"
-		v_pad="0"
-		halign="center"
-		enabled="false"
-		use_ellipses="true"
-		font="SansSerifHugeBold"
-		value="Undefined name" />
-		<texture_picker
-		enabled="false"
-		fallback_image="Generic_Person_Large"
-		follows="left|top|right"
-		height="210"
-		layout="topleft"
-		left="78"
-		name="snapshot"
-		top_pad="4"
-		width="210"/>
-		<texture_picker
-		enabled="false"
-		fallback_image="default_land_picture.j2c"
-		follows="left|top|right"
-		height="210"
-		layout="topleft"
-		left_delta="0"
-		name="snapshot_parcel"
-		top_delta="0"
-		visible="false"
-		width="280"/>
-		<text_editor
-		left="20"
-		top_pad="2"
-		height="16"
-		width="180"
-		layout="topleft"
-		follows="left|top|right"
-		name="aux1"
-		bg_visible="false"
-		border_visible="false"
-		h_pad="0"
-		v_pad="0"
-		word_wrap="true"
-		enabled="false"
-		max_length="117"
-		allow_scroll="false"
-		parse_urls="true"
-		value="Auxilary info field 1"/>
-		<text_editor
-		left_pad="4"
-		top_delta="0"
-		height="16"
-		width="140"
-		layout="topleft"
-		follows="left|top|right"
-		name="aux2"
-		bg_visible="false"
-		border_visible="false"
-		h_pad="0"
-		v_pad="0"
-		word_wrap="true"
-		enabled="false"
-		max_length="117"
-		allow_scroll="false"
-		parse_urls="true"
-		value="Auxilary info field 2"/>
-		<icon
-		follows="top|right"
-		height="16"
-		image_name="Unknown_Icon"
-		layout="topleft"
-		left="20"
-		top_pad="2"
-		name="maturity_icon"
-		width="18" />
-		<text_editor
-		left_pad="4"
-		top_delta="0"
-		height="28"
-		width="302"
-		layout="topleft"
-		follows="left|top|right"
-		name="location"
-		bg_visible="false"
-		border_visible="false"
-		h_pad="0"
-		v_pad="0"
-		word_wrap="true"
-		enabled="false"
-		max_length="117"
-		allow_scroll="false"
-		parse_urls="true"
-		value="Location info field"/>
-		<text_editor
-		left="20"
-		top_pad="12"
-		height="154"
-		width="324"
-		layout="topleft"
-		follows="left|top|right"
-		name="desc"
-		bg_visible="false"
-		border_visible="false"
-		h_pad="0"
-		v_pad="0"
-		word_wrap="true"
-		parse_urls="true"
-		enabled="false"
-		max_length="1000"
-		trusted_content="false"
-		value="You unlock this door with the key of imagination. Beyond it is another dimension: a dimension of sound, a dimension of sight, a dimension of mind. You're moving into a land of both shadow and substance, of things and ideas; you've just crossed over into the Twilight Zone. What you are about to see is real; the litigants on the screen are not actors. They are genuine citizens who, having filed their claims in a real small claims court, have been persuaded to drop their suits there and have them settled here, in this forum... the People's Court."/>
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Open Profile"
-		name="people_profile_btn"
-		top="484"
-		left="3"
-		width="120" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Send Message"
-		name="people_message_btn"
-		width="120"
-		left_pad="1" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Add Friend"
-		name="people_friend_btn"
-		width="120"
-		left_pad="1" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Open Profile"
-		name="group_profile_btn"
-		top="484"
-		left="3"
-		width="120" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Join Chat"
-		name="group_message_btn"
-		width="120"
-		left_pad="1" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Join Group"
-		name="group_join_btn"
-		width="120"
-		left_pad="1" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Teleport"
-		name="teleport_btn"
-		top="484"
-		left="3"
-		width="120" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Show on Map"
-		name="map_btn"
-		width="120"
-		left_pad="1" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Remind me"
-		name="event_reminder_btn"
-		width="120"
-		left_pad="1" />
-		<loading_indicator
-		left="134"
-		top="320"
-		follows="left|top|right"
-		mouse_opaque="false"
-		name="loading"
-		images_per_sec="1.0"
-		tab_stop="false"
-		height="100"
-		width="100"
-		visible="false" >
-			<images>
-				<image name="ProgressLarge_1"/>
-				<image name="ProgressLarge_2"/>
-				<image name="ProgressLarge_3"/>
-				<image name="ProgressLarge_4"/>
-				<image name="ProgressLarge_5"/>
-				<image name="ProgressLarge_6"/>
-				<image name="ProgressLarge_7"/>
-				<image name="ProgressLarge_8"/>
-				<image name="ProgressLarge_9"/>
-				<image name="ProgressLarge_10"/>
-				<image name="ProgressLarge_11"/>
-				<image name="ProgressLarge_12"/>
-			</images>
-		</loading_indicator>
-	</panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile_legacy.xml b/indra/newview/skins/default/xui/en/floater_profile_legacy.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2a896d10796abe463d06208dd50d4cb6859f77dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_legacy.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+  positioning="cascading"
+  can_close="true"
+  can_resize="true"
+  height="580"
+  min_height="350"
+  min_width="260"
+  layout="topleft"
+  name="floater_profile_legacy"
+  save_rect="true"
+  title="PROFILE"
+  width="370">
+    <panel
+      class="panel_profile_legacy_sidetray"
+      name="panel_profile_legacy_sidetray"
+      filename="panel_profile_legacy_sidetray.xml"
+      label="Profile"
+      font="SansSerifBold"
+      follows="all"
+      layout="topleft"
+      min_height="350"
+      left="1"
+      right="-1"
+      top="0"
+      bottom="-8"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_profile_legacy.xml b/indra/newview/skins/default/xui/en/menu_profile_legacy.xml
new file mode 100644
index 0000000000000000000000000000000000000000..93724bbca1a0e59e67f2f1151d08045ddfd660c1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_legacy.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_profile_legacy"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_call
+   label="Open Webprofile..."
+   name="webprofile">
+     <menu_item_call.on_click
+      function="Profile.Action"
+      parameter="webprofile"/>
+  </menu_item_call>
+  <menu_item_separator/>
+  <!--<menu
+	label="Upload profile image"
+	layout="topleft"
+	name="upload_image_menu">
+	  <menu_item_call
+       label="Second Life..."
+       name="upload_second_life">
+		<menu_item_call.on_click
+		 function="Profile.Action"
+		 parameter="upload_sl"/>
+		<menu_item_call.on_enable
+		 function="Profile.Enable"
+		 parameter="can_upload_pic" />
+	  </menu_item_call>
+	  <menu_item_call
+       label="First Life..."
+       name="upload_first_life">
+        <menu_item_call.on_click
+	     function="Profile.Action"
+	     parameter="upload_fl"/>
+        <menu_item_call.on_enable
+		 function="Profile.Enable"
+		 parameter="can_upload_pic" />
+	  </menu_item_call>
+  </menu>-->
+  <menu_item_call
+   label="Share..."
+   name="share">
+     <menu_item_call.on_click
+      function="Profile.Action"
+      parameter="share"/>
+     <menu_item_call.on_enable
+      function="Profile.Enable"
+      parameter="can_share" />
+  </menu_item_call>
+  <menu_item_call
+   label="Call Avatar..."
+   name="call">
+     <menu_item_call.on_click
+      function="Profile.Action"
+      parameter="call"/>
+     <menu_item_call.on_enable
+      function="Profile.Enable"
+      parameter="can_has_telefono" />
+  </menu_item_call>
+  <menu_item_call
+   label="Offer teleport..."
+   name="teleport">
+     <menu_item_call.on_click
+      function="Profile.Action"
+      parameter="teleport"/>
+     <menu_item_call.on_enable
+      function="Profile.Enable"
+      parameter="can_has_teleport" />
+  </menu_item_call>
+  <menu_item_call
+   label="Request teleport..."
+   name="request_teleport">
+     <menu_item_call.on_click
+      function="Profile.Action"
+      parameter="req_teleport"/>
+     <menu_item_call.on_enable
+      function="Profile.Enable"
+      parameter="can_has_teleport" />
+  </menu_item_call>
+  <menu_item_call
+   label="Show on map..."
+   name="map">
+     <menu_item_call.on_click
+      function="Profile.Action"
+      parameter="map"/>
+     <menu_item_call.on_enable
+      function="Profile.Enable"
+      parameter="can_has_map" />
+  </menu_item_call>
+  <menu_item_call
+   label="Pay..."
+   name="pay">
+     <menu_item_call.on_click
+      function="Profile.Action"
+      parameter="pay"/>
+     <menu_item_call.on_enable
+      function="Profile.Enable"
+      parameter="can_has_pay" />
+  </menu_item_call>
+  <menu_item_call
+   label="Report Abuse..."
+   name="report_abuse">
+     <menu_item_call.on_click
+      function="Profile.Action"
+      parameter="report_abuse"/>
+     <menu_item_call.on_enable
+      function="Profile.Enable"
+      parameter="can_drama" />
+  </menu_item_call>
+  <menu_item_separator />
+  <menu_item_call
+   label="Copy Name"
+   name="Copy Name">
+	<menu_item_call.on_click
+	 function="Avatar.CopyData"
+	 parameter="account_name"/>
+	<menu_item_call.on_enable
+	 function="RLV.CanShowName" />
+  </menu_item_call>
+  <menu_item_call
+   label="Copy SLurl"
+   name="Copy SLurl">
+	<menu_item_call.on_click
+	 function="Avatar.CopyData"
+	 parameter="slurl"/>
+	<menu_item_call.on_enable
+	 function="RLV.CanShowName" />
+  </menu_item_call>
+  <menu_item_call
+   label="Copy UUID"
+   name="Copy ID">
+	<menu_item_call.on_click
+	 function="Avatar.CopyData"
+	 parameter="id"/>
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index 0febf62b4355e3b2f7dabb09bf345bbe73b31934..e3fd1cd5a1fab2799f387eada4da0a9ffdc88a7e 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -38,15 +38,28 @@
   name="auto_renew_off">
     Disabled
  </panel.string>
+    <button
+     follows="top|left"
+     height="24"
+     image_hover_unselected="BackButton_Over"
+     image_pressed="BackButton_Press"
+     image_unselected="BackButton_Off"
+     layout="topleft"
+     name="back_btn"
+     left="10"
+     tab_stop="false"
+     top="2"
+     width="30"
+     use_draw_context_alpha="false" />
     <text
      follows="top|left|right"
      font="SansSerifHugeBold"
      height="26"
      layout="topleft"
-     left="12"
+     left_pad="4"
      name="title"
      text_color="LtGray"
-     top="2"
+     top="0"
      value="Classified Info"
      use_ellipses="true"
      width="275" />
@@ -407,7 +420,7 @@
 		         height="23"
 		         label="Teleport"
 		         layout="topleft"
-		         left="2"
+		         left="0"
 		         name="teleport_btn"
 		         top="0"
 		         width="101" />	
@@ -430,6 +443,24 @@
 		         top="0"
 		         width="100" />
 		  </layout_panel>	  
+		  
+		  <layout_panel
+			  follows="bottom|left|right"
+			  height="23"
+			  layout="bottomleft"
+			  left_pad="3"
+			  name="edit_btn_lp"
+		      auto_resize="true"
+			  width="101">
+			  <button
+		         follows="bottom|left|right"
+		         height="23"
+		         label="Edit"
+		         layout="topleft"
+		         name="edit_btn"
+		         top="0"
+		         width="101" />
+		  </layout_panel>
 	   </layout_stack>
     </panel>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
new file mode 100644
index 0000000000000000000000000000000000000000..39f1817705dfece84146b65b9b4c6e3aa55afa16
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ bevel_style="in"
+ follows="left|top|right|bottom"
+ height="569"
+ label="Edit Pick"
+ layout="topleft"
+ left="0"
+ min_height="350"
+ name="panel_edit_pick"
+ help_topic="profile_edit_pick"
+ top="0"
+ width="333">
+ <panel.string
+  name="location_notice">
+    (will update after save)
+ </panel.string>
+  <button
+     follows="top|left"
+     height="24"
+     image_hover_unselected="BackButton_Over"
+     image_pressed="BackButton_Press"
+     image_unselected="BackButton_Off"
+     layout="topleft"
+     name="back_btn"
+     left="10"
+     tab_stop="false"
+     top="2"
+     width="30"
+     use_draw_context_alpha="false" />
+   <text
+     type="string"
+     length="1"
+     follows="top"
+     font="SansSerifHugeBold"
+     height="26"
+     layout="topleft"
+     left_pad="4"
+     name="title"
+     text_color="LtGray"
+     top="2"
+     width="250">
+        Edit Pick
+    </text>
+   <scroll_container
+     color="PanelDefaultBackgroundColor"
+     follows="all"
+     height="502"
+     layout="topleft"
+     left="8"
+     top_pad="10"
+     name="profile_scroll"
+     opaque="true"
+     width="312">
+    <panel
+     name="scroll_content_panel"
+     follows="left|top|right"
+     min_height="300"
+     layout="topleft"
+     top="0"
+     background_visible="false"
+     height="500"
+     left="0"
+     width="285">
+    <texture_picker
+     fallback_image="default_land_picture.j2c"
+     follows="left|top|right"
+     height="197"
+     width="272"
+     layout="topleft"
+     no_commit_on_selection="true"
+     top="10"
+     left="11"
+     name="pick_snapshot" />
+          <icon
+           height="197"
+           image_name="spacer24.tga"
+           layout="topleft"
+           name="edit_icon"
+           label=""
+           tool_tip="Click to select an image"
+           top="10"
+           left="11"
+           width="286" />
+        <text
+         type="string"
+         length="1"
+         follows="left|top|right"
+         height="15"
+         font="SansSerifSmall"
+         font.style="BOLD"
+         layout="topleft"
+         left="10"
+         top="215"
+         name="Name:"
+         text_color="white"
+         width="280">
+            Title:
+        </text>
+        <line_editor
+         follows="left|top|right"
+         font="SansSerif"
+         height="20"
+         layout="topleft"
+         left="10"
+         top_pad="2"
+         max_length_bytes="63"
+         name="pick_name"
+         width="273" />
+        <text
+         type="string"
+         length="1"
+         follows="left|top|right"
+         height="15"
+         font="SansSerifSmall"
+         font.style="BOLD"
+         layout="topleft"
+         left="10"
+         top_pad="20"
+         name="description_label"
+         text_color="white"
+         width="280">
+            Description:
+        </text>
+        <text_editor
+         follows="left|top|right"
+         height="100"
+         width="273"
+         hide_scrollbar="false"
+         layout="topleft"
+         left="10"
+         top_pad="2"
+         max_length="1023"
+         name="pick_desc"
+         spellcheck="true"
+         word_wrap="true" 
+		 show_emoji_helper="true" />
+        <text
+         type="string"
+         length="1"
+         font="SansSerifSmall"
+         font.style="BOLD"
+         follows="left|top|right"
+         height="15"
+         layout="topleft"
+         left="10"
+         name="location_label"
+         text_color="white"
+         top_pad="20"
+         width="280">
+            Location:
+        </text>
+        <text
+         type="string"
+         length="1"
+         follows="left|top|right"
+         height="50"
+         layout="topleft"
+         left="10"
+         name="pick_location"
+         top_pad="2"
+         width="280"
+         word_wrap="true">
+            loading...
+        </text>
+        <button
+         follows="left|top"
+         height="23"
+         label="Set to Current Location"
+         layout="topleft"
+         left="8"
+         top_pad="0"
+         name="set_to_curr_location_btn"
+         width="200" />
+    </panel>
+    </scroll_container>
+    <panel
+     follows="left|right|bottom"
+     height="23"
+     label="bottom_panel"
+     layout="topleft"
+     left="8"
+     name="bottom_panel"
+     top_pad="5"
+     width="315">
+     
+     	 <layout_stack
+		  follows="bottom|left|right"
+		  height="23"
+		  layout="topleft"
+		  name="layout_stack1"
+		  left="0"
+		  orientation="horizontal"
+		  top_pad="0"
+		  width="313">
+		  	 
+		  	 <layout_panel
+			  follows="bottom|left|right"
+			  height="23"
+			  layout="topleft"
+			  left="0"
+			  name="layout_panel1"
+		      auto_resize="true"
+			  width="150">
+		        <button
+		         follows="bottom|left|right"
+		         height="23"
+		         label="Save Pick"
+		         layout="topleft"
+		         name="save_changes_btn"
+		         top="0"
+		         left="1"
+		         width="149" />
+			  </layout_panel>
+			  
+			 <layout_panel
+			  follows="bottom|left|right"
+			  height="23"
+			  layout="topleft"
+			  left_pad="4"
+			  name="layout_panel2"
+		      auto_resize="true"
+			  width="146">
+		        <button
+		         follows="bottom|left|right"
+		         height="23"
+		         label="Cancel"
+		         layout="topleft"
+		         name="cancel_btn"
+		         top="0"
+		         left="1"
+		        width="145" />
+			  </layout_panel>
+	</layout_stack>
+		  
+    </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_event_info.xml b/indra/newview/skins/default/xui/en/panel_event_info.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b065f493c12e4bc0935a2152adcb63aaa4e6e284
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_event_info.xml
@@ -0,0 +1,456 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ follows="all"
+ height="570"
+ layout="topleft"
+ left="0"
+ min_height="350"
+ name="event_info"
+ class="event_info"
+ top="20"
+ width="333">
+  <panel.string name="free">
+   FREE
+  </panel.string>
+  <panel.string name="hours">
+   hours
+  </panel.string>
+  <panel.string name="minutes">
+   minutes
+  </panel.string>
+  <panel.string name="type_mature">
+   Moderate
+  </panel.string>
+  <panel.string name="type_pg">
+  General Content
+  </panel.string>
+  <panel.string name="reminder">
+   Remind
+  </panel.string>
+  <panel.string name="no_reminder">
+   Don't remind
+  </panel.string>
+  <button
+   follows="top|left"
+   height="24"
+   image_hover_unselected="BackButton_Over"
+   image_pressed="BackButton_Press"
+   image_unselected="BackButton_Off"
+   layout="topleft"
+   name="back_btn"
+   left="10"
+   tab_stop="false"
+   top="2"
+   width="30"
+   use_draw_context_alpha="false" />
+  <text
+   follows="top|left|right"
+   font="SansSerifHugeBold"
+   height="26"
+   layout="topleft"
+   left_pad="4"
+   name="title"
+   text_color="LtGray"
+   top="0"
+   value="Event Info"
+   use_ellipses="true"
+   width="275" />
+  <scroll_container
+   color="PanelDefaultBackgroundColor"
+   opaque="true"
+   follows="all"
+   height="502"
+   layout="topleft"
+   left="10"
+   top_pad="10"
+   name="profile_scroll"
+   reserve_scroll_corner="false"
+   width="312">
+    <panel
+     name="scroll_content_panel"
+     follows="left|top"
+     min_height="300"
+     layout="topleft"
+     top="0"
+     background_visible="false"
+     height="610"
+     left="0"
+     width="285">
+     <panel
+     name="snapshot_panel"
+     layout="topleft"
+     follows="left|top|right"
+     height="197"
+     left="10"
+     top="10"
+     width="275">
+      <texture_picker
+       fallback_image="default_land_picture.j2c"
+       enabled="false"
+       follows="left|top|right"
+       height="197"
+       layout="topleft"
+       left="0"
+       name="snapshot"
+       top="0"
+       width="275" />
+    </panel>
+    <text_editor
+     allow_scroll="false"
+     bg_visible="false"
+     follows="left|top|right"
+     h_pad="0"
+     height="35"
+     width="290"
+     layout="topleft"
+     font="SansSerifBig"
+     font.style="BOLD"
+     left="10"
+     top_pad="10"
+     name="name"
+     read_only="true"
+     text_color="white"
+     v_pad="0"
+     value="[name]"
+     use_ellipses="true" />
+    <text
+     follows="left|top"
+     font.style="BOLD"
+     height="10"
+     layout="topleft"
+     left="10"
+     name="event_location_label"
+     text_color="white"
+     top_pad="5"
+     value="Location:"
+     width="250" />
+    <text_editor
+     parse_urls="true"
+     allow_scroll="false"
+     bg_visible="false"
+     follows="left|top"
+     h_pad="0"
+     height="30"
+     layout="topleft"
+     left="10"
+     name="location"
+     read_only="true"
+     top_pad="5"
+     width="290"
+     word_wrap="true"
+     v_pad="0"
+     value="[loading...]" />
+    <text
+     follows="left|top"
+     font.style="BOLD"
+     height="10"
+     layout="topleft"
+     left="10"
+     name="content_type_label"
+     text_color="white"
+     top_pad="10"
+     value="Content Type:"
+     width="140" />
+    <icon
+     follows="top|left"
+     height="16"
+     image_name="Parcel_M_Light"
+     layout="topleft"
+     left_pad="0"
+     name="content_type_moderate"
+     top_pad="-11"
+     width="18" />
+    <icon
+     follows="top|left"
+     height="16"
+     image_name="Parcel_PG_Light"
+     layout="topleft"
+     left_delta="0"
+     name="content_type_general"
+     top_delta="0"
+     width="18" />
+    <text_editor
+     allow_scroll="false"
+     bg_visible="false"
+     follows="left|top|right"
+     h_pad="0"
+     height="18"
+     layout="topleft"
+     left_pad="2"
+     name="content_type"
+     read_only="true"
+     width="130"
+     top_delta="1"
+     v_pad="0"
+     value="[content type]" />
+    <text
+     follows="left|top"
+     font.style="BOLD"
+     height="10"
+     layout="topleft"
+     left="10"
+     name="time_label"
+     text_color="white"
+     top_pad="0"
+     value="Time:"
+     width="140" />
+    <text_editor
+     allow_scroll="false"
+     bg_visible="false"
+     follows="left|top|right"
+     h_pad="0"
+     height="18"
+     layout="topleft"
+     left_pad="0"
+     name="time"
+     read_only="true"
+     width="150"
+     top_pad="-10"
+     v_pad="0"
+     value="[time]" />
+    <text
+     follows="left|top"
+     font.style="BOLD"
+     height="10"
+     layout="topleft"
+     left="10"
+     name="duration_label"
+     text_color="white"
+     top_pad="0"
+     value="Duration:"
+     width="140" />
+    <text_editor
+     allow_scroll="false"
+     bg_visible="false"
+     follows="left|top"
+     h_pad="0"
+     halign="left"
+     height="16"
+     layout="topleft"
+     left_pad="0"
+     name="duration"
+     read_only="true"
+     top_pad="-10"
+     v_pad="0"
+     value="[duration] hours"
+     width="150" />
+    <layout_stack
+     animate="false"
+     name="descr_stack"
+     layout="topleft"
+     follows="all"
+     orientation="vertical"
+     left="10"
+     top_pad="5"
+     width="290"
+     height="215">
+      <layout_panel
+       auto_resize="false"
+       name="host_layout_panel"
+       layout="topleft"
+       follows="all"
+       left="0"
+       top="0"
+       width="290"
+       height="16">
+       <text
+        follows="left|top"
+        font.style="BOLD"
+        height="10"
+        layout="topleft"
+        left="0"
+        name="host_label"
+        text_color="white"
+        top_pad="0"
+        value="Host:"
+        width="140" />
+       <text_editor
+        allow_scroll="false"
+        bg_visible="false"
+        follows="left|top"
+        h_pad="0"
+        halign="left"
+        height="16"
+        layout="topleft"
+        left_pad="0"
+        parse_urls="true"
+        name="host"
+        read_only="true"
+        top_pad="-10"
+        v_pad="0"
+        value="secondlife:///app/agent/00000000-0000-0000-0000-000000000000/inspect"
+        width="150" />
+      </layout_panel>
+      <layout_panel
+       auto_resize="false"
+       name="category_panel"
+       layout="topleft"
+       follows="all"
+       left="0"
+       top="0"
+       width="290"
+       height="16">
+        <text
+         follows="left|top"
+         font.style="BOLD"
+         height="10"
+         layout="topleft"
+         left="0"
+         name="category_label"
+         text_color="white"
+         top="0"
+         value="Category:"
+         width="140" />
+        <text
+         height="16"
+         layout="topleft"
+         follows="top|left"
+         left_pad="0"
+         name="category"
+         top_pad="-10"
+         value="[category]"
+         width="150" />
+      </layout_panel>
+      <layout_panel
+       auto_resize="false"
+       name="cover_panel"
+       layout="topleft"
+       follows="all"
+       left="0"
+       top="0"
+       width="290"
+       height="16">
+        <text
+         follows="left|top"
+         font.style="BOLD"
+         height="10"
+         layout="topleft"
+         left="0"
+         name="cover_label"
+         text_color="white"
+         top="0"
+         value="Cover:"
+         width="140" />
+        <text
+         height="16"
+         layout="topleft"
+         follows="top|left"
+         left_pad="0"
+         name="cover"
+         top_pad="-10"
+         value="L$[cover]"
+       width="150" />
+      </layout_panel>
+      <layout_panel
+       name="descr_layout_panel"
+       layout="topleft"
+       follows="all"
+       left="0"
+       top="0"
+       width="290"
+       height="215">
+        <text
+         auto_resize="false"
+         follows="left|top"
+         font.style="BOLD"
+         height="10"
+         layout="topleft"
+         left="0"
+         name="desc_label"
+         text_color="white"
+         top="0"
+         value="Description:"
+         width="250" />
+        <text_editor
+         parse_urls="true"
+         allow_scroll="true"
+         bg_visible="false"
+         follows="all"
+         h_pad="0"
+         height="200"
+         layout="topleft"
+         left="0"
+         max_length="1023"
+         name="desc"
+         read_only="true"
+         top_pad="7"
+         width="280"
+         v_pad="0"
+         value="[description]"
+         word_wrap="true" />
+      </layout_panel>
+    </layout_stack>
+  </panel>
+</scroll_container>
+<panel
+ follows="left|right|bottom"
+ height="35"
+ layout="topleft"
+ top_pad="5"
+ left="9"
+ name="buttons">
+  <layout_stack
+   follows="bottom|left|right"
+   height="23"
+   layout="topleft"
+   name="layout_stack1"
+   left="0"
+   orientation="horizontal"
+   top_pad="0"
+   width="309">
+    <layout_panel
+     follows="bottom|left|right"
+     height="23"
+     layout="bottomleft"
+     left="0"
+     name="layout_panel1"
+     auto_resize="true"
+     width="101">
+      <button
+       follows="bottom|left|right"
+       height="23"
+       label="Teleport"
+       layout="topleft"
+       left="0"
+       name="teleport_btn"
+       top="0"
+       width="101" />
+    </layout_panel>
+    <layout_panel
+     follows="bottom|left|right"
+     height="23"
+     layout="bottomleft"
+     left_pad="3"
+     name="show_on_map_btn_lp"
+     auto_resize="true"
+     width="100">
+      <button
+       follows="bottom|left|right"
+       height="23"
+       label="Map"
+       layout="topleft"
+       name="show_on_map_btn"
+       top="0"
+       width="100" />
+    </layout_panel>
+    <layout_panel
+     follows="bottom|left|right"
+     height="23"
+     layout="bottomleft"
+     left_pad="3"
+     name="remind_btn_lp"
+     auto_resize="true"
+     width="101">
+      <button
+       follows="bottom|left|right"
+       height="23"
+       label="Remind"
+       layout="topleft"
+       name="remind_btn"
+       top="0"
+       width="101" />
+    </layout_panel>
+  </layout_stack>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml
deleted file mode 100644
index 66c35558b10d93e30f6027ecaa2ac34ce6264715..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml
+++ /dev/null
@@ -1,169 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- follows="all"
- height="566"
- layout="topleft"
- left="1"
- width="780"
- label="Classifieds"
- name="panel_ls_classifieds">
-	<panel
-	 border="false"
-	 follows="top|left|right"
-	 height="53"
-	 layout="topleft"
-	 left="0"
-	 width="780"
-	 name="panel_ls_input">
-		<text
-		 type="string"
-		 length="1"
-		 follows="left|top"
-		 top_pad="5"
-		 layout="topleft"
-		 left="6"
-		 name="search_text"
-		 top="12"
-		 height="16"
-		 width="156">
-		Enter search terms:
-		</text>
-		<search_combo_box
-		 layout="topleft"
-		 follows="left|top|right"
-		 height="23"
-		 left_delta="0"
-		 name="classifieds_edit"
-		 top="29"
-		 width="651" />
-		<combo_box
-		 follows="right|top"
-		 layout="topleft"
-		 height="23"
-		 allow_text_entry="false"
-		 top_delta="0"
-		 left_pad="2"
-		 name="classifieds_category"
-		 width="122">
-			<combo_box.commit_callback
-			 function="CommitSearch" />
-		</combo_box>
-		<check_box
-		 control_name="ShowPGClassifieds"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left="660"
-		 name="pg_all"
-		 top="12"
-		 width="15">
-			<check_box.commit_callback
-			 function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_PG_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_general"
-		 top_delta="-1"
-		 width="18"/>
-		<check_box
-		 control_name="ShowMatureClassifieds"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left_pad="2"
-		 name="mature_all"
-		 top_delta="1"
-		 width="15">
-			<check_box.commit_callback
-			 function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_M_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_moderate"
-		 top_delta="-1"
-		 width="18"/>
-		<check_box
-		 control_name="ShowAdultClassifieds"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left_pad="2"
-		 name="adult_all"
-		 top_delta="1"
-		 width="15">
-			<check_box.commit_callback
-			 function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_R_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_adult"
-		 top_delta="-1"
-		 width="18"/>
-	</panel>
-	<!-- Search Pane -->
-	<panel
-	 border="true"
-	 follows="all"
-	 height="510"
-	 layout="topleft"
-	 left="1"
-	 width="410"
-	 top_pad="1"
-	 name="panel_ls_scrolllist">
-		<scroll_list
-		 draw_heading="true"
-		 follows="all"
-		 height="485"
-		 layout="topleft"
-		 left="0"
-		 name="search_results_classifieds"
-		 top="0"
-		 width="410">
-			<columns
-			 label=""
-			 name="icon"
-			 width="20" />
-			<columns
-			 label="Name"
-			 name="classified_name"
-			 relwidth="0.70" />
-			<columns
-			 label="Listing Price"
-			 name="price"
-			 relwidth="0.3"/>
-		</scroll_list>
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 label="Back"
-	 	 name="classifieds_back"
-		 top_pad="2"
-		 left="3"
-		 width="100" />
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 label="Next"
-		 name="classifieds_next"
-		 width="100"
-		 left_pad="1" />
-	</panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml
deleted file mode 100644
index 57cb4990e408332b97d4607b70899c09ce43c7ed..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml
+++ /dev/null
@@ -1,258 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- follows="all"
- height="566"
- layout="topleft"
- left="1"
- width="780"
- label="Events"
- name="panel_ls_events">
-	<panel
-	 border="false"
-	 follows="top|left|right"
-	 height="53"
-	 layout="topleft"
-	 left="0"
-	 width="780"
-	 name="panel_ls_input">
-		<text
-		 type="string"
-		 length="1"
-		 follows="left|top"
-		 top_pad="5"
-		 layout="topleft"
-		 left="6"
-		 name="search_text"
-		 top="12"
-		 height="16"
-		 width="156">
-		 Enter search terms:
-		</text>
-		<radio_group
-		 left_pad="20"
-		 height="16"
-		 width="300"
-		 layout="topleft"
-		 name="events_search_mode">
-			<radio_item
-			 height="16"
-			 label="Ongoing and Upcoming"
-			 layout="topleft"
-			 name="current"
-			 value="current"
-			 top_pad="0"
-			 width="120" />
-			<radio_item
-			 height="16"
-			 label="By Date"
-			 layout="topleft"
-			 name="date"
-			 value="date"
-			 left_pad="70"
-			 width="120" />
-			<radio_group.commit_callback
-			 function="CommitSearch" />
-		</radio_group>
-		<text
-		 type="string"
-		 length="1"
-		 follows="left|top"
-		 top_delta="0"
-		 layout="topleft"
-		 left_pad="5"
-		 name="events_date"
-		 font.style="BOLD"
-		 height="16"
-		 width="80">
-			4/20
-		</text>
-		<search_combo_box
-		 layout="topleft"
-		 follows="left|top|right"
-		 height="23"
-		 left="6"
-		 name="events_edit"
-		 top="29"
-		 width="651" />
-		<combo_box
-		 follows="right|top"
-		 layout="topleft"
-		 height="23"
-		 top_delta="0"
-		 left_pad="2"
-		 name="events_category"
-		 width="122">
-			<combo_box.item label="Any Category" name="any" value="0" />
-			<combo_box.item label="" value="filter_separator" enabled="false" />
-			<combo_box.item label="Discussion" name="discussion" value="18" />
-			<combo_box.item label="Sports" name="sports" value="19" />
-			<combo_box.item label="Live DJ" name="dj" value="30" />
-			<combo_box.item label="Live Music" name="music" value="20" />
-			<!-- <combo_box.item label="???" name="mystery_category" value="21" /> -->
-			<combo_box.item label="Commercial" name="commercial" value="22" />
-			<combo_box.item label="Nightlife/Entertainment" name="nightlife" value="23" />
-			<combo_box.item label="Games/Contests" name="games" value="24" />
-			<combo_box.item label="Pageants" name="pageants" value="25" />
-			<combo_box.item label="Education" name="education" value="26" />
-			<combo_box.item label="Arts and Culture" name="arts" value="27" />
-			<combo_box.item label="Charity/Support Groups" name="charity" value="28" />
-			<combo_box.item label="Miscellaneous" name="misc" value="29" />
-			<combo_box.commit_callback
-			 function="CommitSearch" />
-		</combo_box>
-		<check_box
-		 control_name="ShowPGEvents"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left="660"
-		 name="pg_all"
-		 top="12"
-		 width="15" >
-		<check_box.commit_callback
-		 function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_PG_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_general"
-		 top_delta="-1"
-		 width="18"/>
-		<check_box
-		 control_name="ShowMatureEvents"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left_pad="2"
-		 name="mature_all"
-		 top_delta="1"
-		 width="15">
-			<check_box.commit_callback
-			 function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_M_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_moderate"
-		 top_delta="-1"
-		 width="18"/>
-		<check_box
-		 control_name="ShowAdultEvents"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left_pad="2"
-		 name="adult_all"
-		 top_delta="1"
-		 width="15">
-			<check_box.commit_callback
-			 function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_R_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_adult"
-		 top_delta="-1"
-		 width="18"/>
-	</panel>
-	<!-- Search Pane -->
-	<panel
-	 border="true"
-	 follows="all"
-	 height="510"
-	 layout="topleft"
-	 left="1"
-	 width="410"
-	 top_pad="1"
-	 name="panel_ls_scrolllist">
-		<scroll_list
-		 draw_heading="true"
-		 follows="all"
-		 height="485"
-		 layout="topleft"
-		 left="0"
-		 name="search_results_events"
-		 sort_ascending="true"
-		 sort_column="3"
-		 top="0"
-		 width="410">
-			<columns
-			 label=""
-			 name="icon"
-			 width="20" />
-			<columns
-			 label="Event Name"
-			 name="name"
-			 relwidth="0.72" />
-			<columns
-			 label="Date/Time"
-			 name="date"
-			 sort_column="time"
-			 relwidth="0.28" />
-			<columns
-			 label="Time"
-			 name="time"
-			 width="0"/>
-		</scroll_list>
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 label="Yesterday"
-		 name="events_yesterday"
-		 top_pad="2"
-		 left="3"
-		 width="100" />
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 label="Today"
-		 name="events_today"
-		 width="100"
-		 left_pad="1" />
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 label="Tomorrow"
-		 name="events_tomorrow"
-		 width="100"
-		 left_pad="1" />
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 image_bottom_pad="2"
-		 image_overlay="Arrow_Left_Off"
-		 image_overlay_alignment="left"
-		 label="Back"
-		 name="events_back"
-		 width="25"
-		 left_pad="1" />
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 image_bottom_pad="2"
-		 image_overlay="Arrow_Right_Off"
-		 image_overlay_alignment="left"
-		 label="Next"
-		 name="events_next"
-		 width="25"
-		 left_pad="1" />
-	</panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml
deleted file mode 100644
index 90001952f7c38528926e77ddb32302e2e0b23bbc..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-	border="false"
-	follows="all"
-	height="566"
-	layout="topleft"
-	left="1"
-	width="780"
-	label="Groups"
-	name="panel_ls_groups">
-	<panel
-		border="false"
-		follows="top|left|right"
-		height="53"
-		layout="topleft"
-		left="0"
-		width="780"
-		name="panel_ls_input">
-		<text
-			type="string"
-			length="1"
-			follows="left|top"
-			top_pad="5"
-			layout="topleft"
-			left="6"
-			name="search_text"
-			top="12"
-			height="16"
-			width="156">
-			Enter search terms:
-		</text>
-		<search_combo_box
-		layout="topleft"
-		follows="left|top|right"
-		height="23"
-		left_delta="0"
-		name="groups_edit"
-		top="29"
-		width="770">
-		</search_combo_box>
-		<check_box
-		control_name="ShowPGGroups"
-		follows="right|top"
-		height="16"
-		label=""
-		layout="topleft"
-		left="660"
-		name="pg_all"
-		top="12"
-		width="15"
-		visible="false"/>
-		<icon
-		follows="right|top"
-		height="16"
-		image_name="Parcel_PG_Dark"
-		layout="topleft"
-		left_pad="2"
-		name="rating_icon_general"
-		top_delta="-1"
-		width="18"
-		visible="false"/>
-		<check_box
-		control_name="ShowMatureGroups"
-		follows="right|top"
-		height="16"
-		label=""
-		layout="topleft"
-		left_pad="2"
-		name="mature_all"
-		top_delta="1"
-		width="15"
-		visible="false"/>
-		<icon
-		follows="right|top"
-		height="16"
-		image_name="Parcel_M_Dark"
-		layout="topleft"
-		left_pad="2"
-		name="rating_icon_moderate"
-		top_delta="-1"
-		width="18"
-		visible="false"/>
-		<check_box
-		control_name="ShowAdultGroups"
-		follows="right|top"
-		height="16"
-		label=""
-		layout="topleft"
-		left_pad="2"
-		name="adult_all"
-		top_delta="1"
-		width="15"
-		visible="false"/>
-		<icon
-		follows="right|top"
-		height="16"
-		image_name="Parcel_R_Dark"
-		layout="topleft"
-		left_pad="2"
-		name="rating_icon_adult"
-		top_delta="-1"
-		width="18"
-		visible="false"/>
-	</panel>
-	<!-- Search Pane -->
-	<panel
-		border="true"
-		follows="all"
-		height="510"
-		layout="topleft"
-		left="1"
-		width="410"
-		top_pad="1"
-		name="panel_ls_scrolllist">
-		<scroll_list
-			draw_heading="true"
-			follows="all"
-			height="485"
-			layout="topleft"
-			left="0"
-			name="search_results_groups"
-			top="0"
-			width="410">
-			<columns
-			label=""
-			name="icon"
-			width="20" />
-			<columns
-			label="Group Name"
-			name="group_name"
-			relwidth="0.72" />
-			<columns
-			label="Members"
-			name="members"
-			relwidth="0.25" />
-			<columns
-			label="Score"
-			name="score"
-			width="0" />
-		</scroll_list>
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Back"
-		name="groups_back"
-		top_pad="2"
-		left="3"
-		width="100" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Next"
-		name="groups_next"
-		width="100"
-		left_pad="1" />
-	</panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml
deleted file mode 100644
index bb03a1e9995b765a5386002da4a82bba89cb7c77..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml
+++ /dev/null
@@ -1,281 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-	border="false"
-	follows="all"
-	height="566"
-	layout="topleft"
-	left="1"
-	width="780"
-	label="Land Sales"
-	name="panel_ls_land">
-	<panel
-		border="false"
-		follows="top|left|right"
-		height="53"
-		layout="topleft"
-		left="0"
-		width="780"
-		name="panel_ls_input">
-		<check_box
-		 control_name="ShowPGLand"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left="660"
-		 name="pg_all"
-		 top="12"
-		 width="15">
-            <check_box.commit_callback
-             function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_PG_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_general"
-		 top_delta="-1"
-		 width="18"/>
-		<check_box
-		 control_name="ShowMatureLand"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left_pad="2"
-		 name="mature_all"
-		 top_delta="1"
-		 width="15">
-            <check_box.commit_callback
-             function="CommitSearch" />
-        </check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_M_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_moderate"
-		 top_delta="-1"
-		 width="18"/>
-		<check_box
-		 control_name="ShowAdultLand"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left_pad="2"
-		 name="adult_all"
-		 top_delta="1"
-         width="15">
-            <check_box.commit_callback
-             function="CommitSearch" />
-        </check_box>
-		<icon
-		follows="right|top"
-		height="16"
-		image_name="Parcel_R_Dark"
-		layout="topleft"
-		left_pad="2"
-		name="rating_icon_adult"
-		top_delta="-1"
-		width="18"/>
-		<text
-			type="string"
-			length="1"
-			follows="left|top"
-			layout="topleft"
-			left="6"
-			name="search_text"
-			top="12"
-			height="16"
-			width="256">
-			Enter search terms:
-		</text>
-		<combo_box
-			control_name="FindLandType"
-			follows="left|top"
-			layout="topleft"
-			height="23"
-			allow_text_entry="false"
-			top_pad="2"
-			left="6"
-			name="land_category"
-			width="122">
-                <combo_box.item label="All Categories" name="All" value="All"/>
-                <combo_box.item label="Auction" name="Auction" value="Auction"/>
-                <combo_box.item label="Mainland Sales" name="Mainland" value="Mainland"/>
-                <combo_box.item label="Estate Sales" name="Estate" value="Estate"/>
-                <combo_box.commit_callback
-                 function="CommitSearch" />
-		</combo_box>
-		<check_box
-		 control_name="FindLandPrice"
-		 follows="left|top"
-		 height="16"
-		 label="Price &lt;"
-		 layout="topleft"
-		 left_pad="3"
-		 name="price_check"
-		 top_delta="3"
-		 width="40" >
-            <check_box.commit_callback
-             function="CommitSearch" />
-        </check_box>
-		<line_editor
-		 enabled_control="FindLandPrice"
-		 bevel_style="none"
-		 border_style="line"
-		 border.border_thickness="0"
-		 commit_on_focus_lost="false"
-		 follows="left|top"
-		 height="18"
-		 left_pad="20"
-		 name="edit_price"
-		 top_delta="-1"
-		 width="40" >
-            <line_editor.commit_callback
-             function="CommitSearch" />
-        </line_editor>
-		<check_box
-		 control_name="FindLandArea"
-		 follows="left|top"
-		 height="16"
-		 label="Area &gt;"
-		 layout="topleft"
-		 left_pad="3"
-		 name="area_check"
-		 top_delta="1"
-		 width="40" >
-            <check_box.commit_callback
-             function="CommitSearch" />
-        </check_box>
-		<line_editor
-		enabled_control="FindLandArea"
-		bevel_style="none"
-		border_style="line"
-		border.border_thickness="0"
-		commit_on_focus_lost="false"
-		follows="left|top"
-		height="18"
-		left_pad="20"
-		name="edit_area"
-		top_delta="-1"
-		width="40" >
-            <line_editor.commit_callback
-             function="CommitSearch" />
-        </line_editor>
-		<text
-         type="string"
-         length="1"
-         follows="left|top"
-         layout="topleft"
-         left="365"
-         name="sort_text"
-         top="12"
-         height="16"
-         width="98">
-         Sort results by:
-		</text>
-		<check_box
-         follows="left|top"
-         height="16"
-         label="Ascending"
-         layout="topleft"
-         left_pad="3"
-         name="ascending_check"
-         width="100" >
-            <check_box.commit_callback
-             function="CommitSearch" />
-        </check_box>
-		<combo_box
-         follows="left|top"
-         layout="topleft"
-         height="23"
-         allow_text_entry="false"
-         left_delta="-102"
-         top_pad="1"
-         name="land_sort_combo"
-         width="118">
-			<combo_box.item label="Name" name="Name_item" value="Name"/>
-			<combo_box.item label="Price" name="Price_item" value="Price"/>
-			<combo_box.item label="Price per meter" name="PPM_item" value="PPM"/>
-			<combo_box.item label="Area" name="Area_item" value="Area"/>
-            <combo_box.commit_callback
-             function="CommitSearch" />
-		</combo_box>
-		<button
-		 follows="top|right"
-		 height="23"
-		 label="Search"
-		 layout="topleft"
-		 left="678"
-		 top_delta="0"
-		 name="land_find"
-		 width="100" />
-	</panel>
-	<!-- Search Pane -->
-	<panel
-     border="true"
-     follows="all"
-     height="510"
-     layout="topleft"
-     left="1"
-     width="410"
-     top_pad="1"
-     name="panel_ls_scrolllist">
-		<scroll_list
-         draw_heading="true"
-         follows="all"
-         height="485"
-         layout="topleft"
-         left="0"
-         name="search_results_land"
-         top="0"
-         width="410">
-			<columns
-			 label=""
-			 name="icon"
-			 width="20" />
-			 <columns
-			 label="Name"
-			 name="land_name"
-			 relwidth="0.45" />
-			<columns
-			 label="Price"
-			 name="price"
-			 relwidth="0.1" />
-            <columns
-			 label="Area"
-			 name="area"
-			 relwidth="0.1" />
-            <columns
-			 label="L$/m"
-			 name="ppm"
-			 relwidth="0.1" />
-			<columns
-			 label="Type"
-			 name="land_type"
-			 relwidth="0.2" />
-		</scroll_list>
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 label="Back"
-		 name="land_back"
-		 top_pad="2"
-		 left="3"
-		 width="100" />
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 label="Next"
-		 name="land_next"
-		 width="100"
-		 left_pad="1" />
-	</panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml
deleted file mode 100644
index 28df02a7e3ced559795525a87414e0945231b539..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-	border="false"
-	follows="all"
-	height="566"
-	layout="topleft"
-	left="1"
-	width="780"
-	label="People"
-	name="panel_ls_people">
-	<panel
-		border="false"
-		follows="top|left|right"
-		height="53"
-		layout="topleft"
-		left="0"
-		width="780"
-		name="panel_ls_input">
-		<text
-			type="string"
-			length="1"
-			follows="left|top"
-			top_pad="5"
-			layout="topleft"
-			left="6"
-			name="search_text"
-			top="12"
-			height="16"
-			width="156">
-			Enter search terms:
-		</text>
-		<search_combo_box
-		layout="topleft"
-		follows="left|top|right"
-		height="23"
-		left_delta="0"
-		name="people_edit"
-		top="29"
-		width="770">
-		</search_combo_box>
-	</panel>
-	<!-- Search Pane -->
-	<panel
-		border="true"
-		follows="all"
-		height="510"
-		layout="topleft"
-		left="1"
-		width="410"
-		top_pad="1"
-		name="panel_ls_scrolllist">
-		<scroll_list
-			content_type="Agents"
-			draw_heading="true"
-			follows="all"
-			height="485"
-			layout="topleft"
-			left="0"
-			name="search_results_people"
-			top="0"
-			width="410">
-			<columns
-			label=""
-			name="icon"
-			width="20" />
-			<columns
-			label="Name"
-			name="username"
-			relwidth="1" />
-		</scroll_list>
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Back"
-		name="people_back"
-		top_pad="2"
-		left="3"
-		width="100" />
-		<button
-		layout="topleft"
-		follows="left|bottom"
-		height="23"
-		label="Next"
-		name="people_next"
-		width="100"
-		left_pad="1" />
-	</panel>
-</panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml
deleted file mode 100644
index 09c142b8fc18688df44226384e6e7ae8a28a72ca..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml
+++ /dev/null
@@ -1,169 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- follows="all"
- height="566"
- layout="topleft"
- left="1"
- width="780"
- label="Places"
- name="panel_ls_places">
-	<panel
-	 border="false"
-	 follows="top|left|right"
-	 height="53"
-	 layout="topleft"
-	 left="0"
-	 width="780"
-	 name="panel_ls_input">
-		<text
-		 type="string"
-		 length="1"
-		 follows="left|top"
-		 top_pad="5"
-		 layout="topleft"
-		 left="6"
-		 name="search_text"
-		 top="12"
-		 height="16"
-		 width="156">
-		Enter search terms:
-		</text>
-		<search_combo_box
-		 layout="topleft"
-		 follows="left|top|right"
-		 height="23"
-		 left_delta="0"
-		 name="places_edit"
-		 top="29"
-		 width="651" />
-		<combo_box
-		 follows="right|top"
-		 layout="topleft"
-		 height="23"
-		 allow_text_entry="false"
-		 top_delta="0"
-		 left_pad="2"
-		 name="places_category"
-		 width="122">
-			<combo_box.commit_callback
-			 function="CommitSearch" />
-		</combo_box>
-		<check_box
- 		 control_name="ShowPGSims"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left="660"
-		 name="pg_all"
-		 top="12"
-		 width="15">
-			<check_box.commit_callback
-			 function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_PG_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_general"
-		 top_delta="-1"
-		 width="18"/>
-		<check_box
-		 control_name="ShowMatureSims"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left_pad="2"
-		 name="mature_all"
-		 top_delta="1"
-		 width="15">
-			<check_box.commit_callback
-			 function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_M_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_moderate"
-		 top_delta="-1"
-		 width="18"/>
-		<check_box
-		 control_name="ShowAdultSims"
-		 follows="right|top"
-		 height="16"
-		 label=""
-		 layout="topleft"
-		 left_pad="2"
-		 name="adult_all"
-		 top_delta="1"
-		 width="15">
-			<check_box.commit_callback
-			 function="CommitSearch" />
-		</check_box>
-		<icon
-		 follows="right|top"
-		 height="16"
-		 image_name="Parcel_R_Dark"
-		 layout="topleft"
-		 left_pad="2"
-		 name="rating_icon_adult"
-		 top_delta="-1"
-		 width="18"/>
-	</panel>
-	<!-- Search Pane -->
-	<panel
-	 border="true"
-	 follows="all"
-	 height="510"
-	 layout="topleft"
-	 left="1"
-	 width="410"
-	 top_pad="1"
-	 name="panel_ls_scrolllist">
-		<scroll_list
-		 draw_heading="true"
-		 follows="all"
-		 height="485"
-		 layout="topleft"
-		 left="0"
-		 name="search_results_places"
-		 top="0"
-		 width="410">
-			<columns
-			 label=""
-			 name="icon"
-			 width="20" />
-			<columns
-			 label="Name"
-			 name="place_name"
-			 relwidth="0.81" />
-			<columns
-			 label="Traffic"
-			 name="dwell"
-			 relwidth="0.16" />
-		</scroll_list>
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 label="Back"
-		 name="places_back"
-		 top_pad="2"
-		 left="3"
-		 width="100" />
-		<button
-		 layout="topleft"
-		 follows="left|bottom"
-		 height="23"
-		 label="Next"
-		 name="places_next"
-		 width="100"
-		 left_pad="1" />
-	</panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml
deleted file mode 100644
index 382a5e8945eafd325fbbb81c5225acdb8c52edc9..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-border="false"
-follows="all"
-height="566"
-layout="topleft"
-left="1"
-width="780"
-label="Websearch"
-name="panel_ls_web">
-	<web_browser
-	 top="5"
-	 bottom="-1"
-	 left="5"
-	 right="-5"
-	 layout="topleft"
-	 follows="all"
-	 name="search_browser"
-	 trusted_content="true"
-	 start_url="about:blank" />
-</panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
new file mode 100644
index 0000000000000000000000000000000000000000..06ac5450355ecd17dfee5382f556351dfcd38590
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ follows="all"
+ height="570"
+ layout="topleft"
+ left="0"
+ min_height="350"
+ name="panel_pick_info"
+ help_topic="profile_pick_info"
+ top="0"
+ width="333">
+    <button
+     follows="top|left"
+     height="24"
+     image_hover_unselected="BackButton_Over"
+     image_pressed="BackButton_Press"
+     image_unselected="BackButton_Off"
+     layout="topleft"
+     name="back_btn"
+     left="10"
+     tab_stop="false"
+     top="2"
+     width="30"
+     use_draw_context_alpha="false" />
+    <text
+     follows="top|left|right"
+     font="SansSerifHugeBold"
+     height="26"
+     layout="topleft"
+     left_pad="4"
+     name="title"
+     text_color="LtGray"
+     top="2"
+     value="Pick Info"
+     use_ellipses="true"
+     width="275" />
+    <scroll_container
+     color="PanelDefaultBackgroundColor"
+     opaque="true"
+     follows="all"
+     height="503"
+     layout="topleft"
+     left="8"
+     top_pad="10"
+     name="profile_scroll"
+     width="312">
+    <panel
+     name="scroll_content_panel"
+     follows="left|top|right"
+     min_height="300"
+     layout="topleft"
+     top="0"
+     background_visible="false"
+     height="400"
+     left="0"
+     width="285">
+        <texture_picker
+         fallback_image="default_land_picture.j2c"
+         enabled="false"
+         follows="left|top|right"
+         height="197"
+         layout="topleft"
+         left="11"
+         name="pick_snapshot"
+         top="10"
+         width="272" />
+        <text_editor
+         allow_scroll="false"
+         bg_visible="false"
+         follows="left|top|right"
+         h_pad="0"
+         height="35"
+         width="280"
+         layout="topleft"
+         font="SansSerifBig"
+         font.style="BOLD"
+         left="10"
+         top_pad="10"
+         name="pick_name"
+         read_only="true"
+         text_color="white"
+         v_pad="0"
+         value="[name]"
+         use_ellipses="true" />
+        <text_editor
+         allow_scroll="false"
+         bg_visible="false"
+         follows="left|top|right"
+         h_pad="0"
+         height="25"
+         layout="topleft"
+         left="10"
+         name="pick_location"
+         read_only="true"
+         width="280"
+         word_wrap="true"
+         v_pad="0"
+         value="[loading...]" />
+        <text_editor
+         bg_readonly_color="DkGray2"
+         follows="all"
+         height="100"
+         width="280"
+         parse_urls="true"	
+         layout="topleft"
+         left="10"
+         top_pad="2"
+         max_length="1023"
+         name="pick_desc"
+         read_only="true"
+         text_readonly_color="white"
+         value="[description]"
+         wrap="true" />
+    </panel>
+    </scroll_container>
+    <panel
+     follows="left|right|bottom"
+     height="23"
+     layout="topleft"
+     top_pad="5"
+     left="8"
+     name="buttons">
+       
+       <layout_stack
+		  follows="bottom|left|right"
+		  height="23"
+		  layout="topleft"
+		  name="layout_stack1"
+		  left="0"
+		  orientation="horizontal"
+		  top_pad="0"
+		  width="312">
+		  
+		  <layout_panel
+			  follows="bottom|left|right"
+			  height="23"
+			  layout="bottomleft"
+			  left="0"
+			  name="layout_panel1"
+		      auto_resize="true"
+			  width="101">
+			  <button
+			  	 follows="bottom|left|right"
+		         height="23"
+		         label="Teleport"
+		         layout="topleft"
+		         name="teleport_btn"
+		         top="0"
+		         width="101" />
+		  </layout_panel>
+		  
+		  <layout_panel
+			  follows="bottom|left|right"
+			  height="23"
+			  layout="bottomleft"
+			  left_pad="3"
+			  name="show_on_map_btn_lp"
+		      auto_resize="true"
+			  width="100">
+			  <button
+		         follows="bottom|left|right"
+		         height="23"
+		         label="Map"
+		         layout="topleft"
+		         name="show_on_map_btn"
+		         top_pad="0"
+		         width="100" />
+		  </layout_panel>	  
+		  
+		  <layout_panel
+			  follows="bottom|left|right"
+			  height="23"
+			  layout="bottomleft"
+			  left_pad="3"
+			  name="edit_btn_lp"
+		      auto_resize="true"
+			  width="101">
+			  <button
+		         follows="bottom|left|right"
+		         height="23"
+		         label="Edit"
+		         layout="topleft"
+		         name="edit_btn"
+		         top_pad="0"
+		         width="101" />
+		  </layout_panel>
+	   </layout_stack>
+    </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8e32d3e70191945d8b61f5506f63186aa9ea727f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_firstlife.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ label="First Life"
+ height="360"
+ width="304"
+ name="avatar_firstlife_tab">
+  <panel
+   name="avatar_info_top"
+   follows="top|left|right"
+   top="0"
+   left="0"
+   height="129"
+   width="304"
+   layout="topleft">
+    <texture_picker
+     default_image_name="Generic_Person_Large"
+     fallback_image="Generic_Person_Large"
+     follows="left|top"
+     height="143"
+     label=""
+     layout="topleft"
+     left="5"
+     name="fl_profile_pic"
+     no_commit_on_selection="true"
+     tool_tip="Click to choose a picture"
+     top="6"
+     width="120" />
+  </panel>
+  <text_editor
+   type="string"
+   follows="all"
+   left="3"
+   height="200"
+   layout="topleft"
+   max_length="65000"
+   name="fl_about"
+   top="134"
+   right="-4"
+   bg_readonly_color="DkGray2"
+   text_readonly_color="White"
+   commit_on_focus_lost="true"
+   word_wrap="true" 
+   show_emoji_helper="true" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ed0b4a8825ed949560b73303ee90184e9eebd7c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_group_list_item.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="top|left|right"
+ height="85"
+ layout="topleft"
+ left="0"
+ name="panel_group_item"
+ top="0"
+ width="313">
+  <icon
+   follows="all"
+   height="85"
+   image_name="ListItem_Over"
+   right="-2"
+   mouse_opaque="false"
+   name="hovered_icon"
+   top="1"
+   scale_image="true"
+   visible="false"
+   width="308"/>
+  <icon
+   follows="all"
+   height="85"
+   image_name="ListItem_Select"
+   right="-2"
+   mouse_opaque="false"
+   name="selected_icon"
+   top="1"
+   scale_image="true"
+   visible="false"
+   width="308"/>
+  <texture_picker
+   allow_no_texture="true"
+   fallback_image="Generic_Group_Large"
+   enabled="false"
+   follows="left|top"
+   height="80"
+   layout="topleft"
+   left="10"
+   mouse_opaque="false"
+   name="picture"
+   tab_stop="false"
+   top="10"
+   top_pad="10"
+   width="90" />
+  <text
+   follows="top|left|right"
+   font="SansSerifSmall"
+   height="15"
+   layout="topleft"
+   left="110"
+   name="name"
+   text_color="white"
+   top="9"
+   use_ellipses="true"
+   width="193"
+   word_wrap="false" />
+  <expandable_text
+   follows="top|left|right"
+   font="SansSerifSmall"
+   height="55"
+   layout="topleft"
+   left="103"
+   name="description"
+   textbox.max_length="1024"
+   textbox.show_context_menu="false"
+   textbox.word_wrap="true"
+   top_pad="0"
+   width="178" />
+  <button
+   follows="right"
+   height="20"
+   image_overlay="ForwardArrow_Off"
+   layout="topleft"
+   left_pad="5"
+   right="-8"
+   name="info_chevron"
+   top_delta="24"
+   width="20" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b09eaa02455a50b3f59ce5087bfb0b54ff63c22e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_groups.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bg_opaque_color="PanelDefaultBackgroundColor"
+ background_visible="true"
+ background_opaque="true"
+ follows="all"
+ height="360"
+ label="Groups"
+ layout="topleft"
+ left="0"
+ name="panel_profile_groups"
+ top_pad="0"
+ width="304">
+ <text
+  type="string"
+  follows="all"
+  height="35"
+  layout="topleft"
+  left="6"
+  right="-6"
+  name="groups_panel_text"
+  wrap="true"
+  top="10">
+ No Groups
+ </text>
+ <flat_list_view
+  color="PanelDefaultBackgroundColor"
+  follows="all"
+  layout="topleft"
+  left="0"
+  right="-1"
+  name="groups_detail_list"
+  opaque="true"
+  top="0"
+  height="360" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a99e004b599838c74ea628b56ef6f4782972eebe
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_interests.xml
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ label="Interests"
+ height="360"
+ width="304"
+ name="avatar_interests_tab">
+  <text
+   font="SansSerifSmall"
+   text_color="White_50"
+   width="190"
+   follows="top|left|right"
+   layout="topleft"
+   mouse_opaque="false"
+   type="string"
+   height="16"
+   length="1"
+   left="3"
+   name="i_want_label"
+   top="2">
+   I want to:
+  </text>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Build"
+   layout="topleft"
+   top_pad="4"
+   left="25"
+   name="wanna_build"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Explore"
+   layout="topleft"
+   top_delta="0"
+   left_pad="4"
+   name="wanna_explore"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Meet"
+   layout="topleft"
+   top_pad="4"
+   left="25"
+   name="wanna_yiff"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Be Hired"
+   layout="topleft"
+   top_delta="0"
+   left_pad="4"
+   name="wanna_work"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Group"
+   layout="topleft"
+   top_pad="4"
+   left="25"
+   name="wanna_group"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Buy"
+   layout="topleft"
+   top_delta="0"
+   left_pad="4"
+   name="wanna_buy"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Sell"
+   layout="topleft"
+   top_pad="4"
+   left="25"
+   name="wanna_sell"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Hire"
+   layout="topleft"
+   top_delta="0"
+   left_pad="4"
+   name="wanna_hire"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <line_editor
+   top_pad="4"
+   follows="left|top|right"
+   height="20"
+   left="25"
+   text_pad_left="5"
+   name="wanna_something"
+   right="-40">
+    <line_editor.commit_callback
+     function="Profile.CommitInterest" />
+  </line_editor>
+
+  <text
+   font="SansSerifSmall"
+   text_color="White_50"
+   width="190"
+   follows="top|left|right"
+   layout="topleft"
+   mouse_opaque="false"
+   type="string"
+   height="16"
+   length="1"
+   left="3"
+   name="skills_label"
+   top_pad="8">
+   Skills:
+  </text>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Textures"
+   layout="topleft"
+   top_pad="4"
+   left="25"
+   name="can_texture"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Architecture"
+   layout="topleft"
+   top_delta="0"
+   left_pad="4"
+   name="can_architect"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Modeling"
+   layout="topleft"
+   top_pad="4"
+   left="25"
+   name="can_model"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Event Planning"
+   layout="topleft"
+   top_delta="0"
+   left_pad="4"
+   name="can_event"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Scripting"
+   layout="topleft"
+   top_pad="4"
+   left="25"
+   name="can_script"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <check_box
+   height="16"
+   initial_value="false"
+   label="Custom Characters"
+   layout="topleft"
+   top_delta="0"
+   left_pad="4"
+   name="can_characters"
+   width="140">
+    <check_box.commit_callback
+     function="Profile.CommitInterest" />
+  </check_box>
+  <line_editor
+   top_pad="4"
+   follows="left|top|right"
+   height="20"
+   left="25"
+   text_pad_left="5"
+   name="can_something"
+   right="-40">
+    <line_editor.commit_callback
+     function="Profile.CommitInterest" />
+  </line_editor>
+  <text
+   top_pad="8"
+   font="SansSerifSmall"
+   text_color="White_50"
+   width="190"
+   follows="top|left|right"
+   layout="topleft"
+   mouse_opaque="false"
+   type="string"
+   height="16"
+   length="1"
+   left="3"
+   name="language_label" >
+   Languages:
+  </text>
+  <line_editor
+   top_pad="4"
+   follows="left|top|right"
+   height="20"
+   left="25"
+   text_pad_left="5"
+   name="languages"
+   right="-40">
+    <line_editor.commit_callback
+     function="Profile.CommitInterest" />
+  </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..295e001f138c3bb28006b30422e2f745694aaaa8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_notes.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ label="Notes"
+ height="360"
+ width="304"
+ name="avatar_notes_tab">
+  <text
+   font="SansSerifSmall"
+   text_color="White_50"
+   width="190"
+   follows="top|left|right"
+   layout="topleft"
+   mouse_opaque="false"
+   type="string"
+   height="16"
+   length="1"
+   left="3"
+   name="notes_label"
+   top="2">
+   Private notes:
+  </text>
+  <text_editor
+   type="string"
+   follows="all"
+   left="3"
+   height="320"
+   layout="topleft"
+   max_length="65530"
+   name="notes"
+   top_pad="4"
+   right="-4"
+   bg_readonly_color="DkGray2"
+   text_readonly_color="White"
+   commit_on_focus_lost="true"
+   word_wrap="true"
+   show_emoji_helper="true" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3cd7d825d781e3e66f4581e4939d8ab878c56131
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_picks.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bg_opaque_color="PanelDefaultBackgroundColor"
+ background_visible="true"
+ background_opaque="true"
+ follows="all"
+ height="360"
+ label="Picks"
+ layout="topleft"
+ left="0"
+ name="panel_profile_picks"
+ top="0"
+ width="304">
+ <text
+  type="string"
+  follows="all"
+  height="35"
+  layout="topleft"
+  left="6"
+  right="-6"
+  name="picks_panel_text"
+  wrap="true"
+  top="10">
+ No Picks
+ </text>
+ <accordion
+  fit_parent="true" 
+  follows="all"
+  height="332"
+  layout="topleft"
+  left="0"
+  right="-1"
+  name="accordion"
+  top="0"
+  single_expansion="true">
+   <accordion_tab
+    layout="topleft"
+    height="101"
+    min_height="150"
+    name="tab_picks"
+    title="Picks"
+    visible="true">
+     <flat_list_view
+      color="PanelDefaultBackgroundColor"
+      follows="all"
+      layout="topleft"
+      left="0"
+      name="picks_list"
+      opaque="true"
+      top="0"
+      width="313" />
+   </accordion_tab>
+   <accordion_tab
+    layout="topleft"
+    height="101"
+    name="tab_classifieds"
+    title="Classifieds"
+    visible="true">
+     <flat_list_view
+      color="PanelDefaultBackgroundColor"
+      follows="all"
+      layout="topleft"
+      left="0"
+      name="classifieds_list"
+      opaque="true"
+      top="0"
+      width="313" />
+    </accordion_tab>
+  </accordion>
+  <panel
+   bg_opaque_color="PanelDefaultBackgroundColor"
+   background_visible="true"
+   background_opaque="true"
+   follows="bottom|left|right"
+   layout="topleft"
+   left="0"
+   height="30"
+   name="buttons_cucks"
+   top_pad="0"
+   width="304">
+    <layout_stack
+     follows="bottom|left|right"
+     height="28"
+     layout="topleft"
+     left="2"
+     name="buttons_cucks_ls"
+     orientation="horizontal"
+     top="0"
+     width="304">
+		  <layout_panel
+       follows="bottom|left|right"
+       height="28"
+       layout="topleft"
+       left="0"
+       name="info_btn_lp"
+       auto_resize="true"
+       top="0"
+       width="95">
+        <button
+         enabled="false"
+         follows="top|left|right"
+         height="23"
+         label="Info"
+         layout="topleft"
+         name="info_btn"
+         tab_stop="false"
+         tool_tip="Show pick information"
+         width="95" />
+		  </layout_panel>
+		  <layout_panel
+       follows="bottom|left|right"
+       height="28"
+       layout="bottomleft"
+       left_pad="2"
+       name="teleport_btn_lp"
+       auto_resize="true"
+       width="117">
+        <button
+         enabled="false"
+         follows="top|left|right"
+         height="23"
+         label="Teleport"
+         layout="topleft"
+         name="teleport_btn"
+         tab_stop="false"
+         tool_tip="Teleport to the corresponding area"
+         width="117" />
+		  </layout_panel>
+		  <layout_panel
+       follows="bottom|left|right"
+       height="28"
+       layout="bottomleft"
+       name="show_on_map_btn_lp"
+       auto_resize="true"
+       left_pad="2"
+       width="90">
+        <button
+         enabled="false"
+         follows="top|left|right"
+         height="23"
+         label="Map"
+         layout="topleft"
+         name="show_on_map_btn"
+         tab_stop="false"
+         tool_tip="Show the corresponding area on the World Map"
+         width="88" />
+		  </layout_panel>
+	  </layout_stack>
+	</panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml
new file mode 100644
index 0000000000000000000000000000000000000000..13560cd0f10c755a59075e040c7d2c6ab7318f48
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_secondlife.xml
@@ -0,0 +1,308 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="all"
+ label="Second Life"
+ height="360"
+ width="304"
+ class="panel_avatar_secondlife"
+ name="avatar_secondlife_tab">
+  <layout_stack
+    follows="all"
+    animate="false"
+    top="0"
+    height="360"
+    left="0"
+    width="304"
+    layout="topleft"
+    orientation="vertical"
+    show_drag_handle="false">
+    <layout_panel
+     name="avatar_info_top"
+     follows="top|left|right"
+     top="0"
+     left="0"
+     height="125"
+     right="-1"
+     auto_resize="false"
+     layout="topleft">
+      <texture_picker
+       default_image_name="Generic_Person_Large"
+       fallback_image="Generic_Person_Large"
+       follows="left|top"
+       height="143"
+       label=""
+       layout="topleft"
+       left="5"
+       name="sl_profile_pic"
+       no_commit_on_selection="true"
+       tool_tip="Click to choose a picture"
+       top="0"
+       width="120" />
+      <text
+       font="SansSerifSmall"
+       text_color="White_50"
+       width="87"
+       follows="top|left"
+       layout="topleft"
+       mouse_opaque="false"
+       type="string"
+       height="16"
+       length="1"
+       left="129"
+       name="rezday_label"
+       top_delta="0">
+        Born:
+      </text>
+      <icon
+       height="16"
+       width="16"
+       visible="false"
+       image_name="Cake"
+       tool_tip="Happy rezday"
+       mouse_opaque="true"
+       name="cake"
+       left_pad="2" />
+      <text
+       font="SansSerifSmall"
+       text_color="ProfileOnlineIndicatorColor"
+       width="57"
+       follows="right|top"
+       layout="topleft"
+       mouse_opaque="false"
+       type="string"
+       height="16"
+       length="1"
+       right="-15"
+       name="online"
+       top_delta="0" >
+        Online
+      </text>
+      <icon
+       follows="right|top"
+       height="14"
+       visible="false"
+       image_name="AccountLevel_Internal"
+       layout="topleft"
+       right="-1"
+       top_delta="0"
+       mouse_opaque="false"
+       name="account_type_internal"
+       width="14" />
+      <icon
+       follows="right|top"
+       height="14"
+       visible="false"
+       image_name="AccountLevel_Premium"
+       layout="topleft"
+       right="-1"
+       top_delta="0"
+       mouse_opaque="false"
+       name="account_type_premium"
+       width="14" />
+      <icon
+       follows="right|top"
+       height="14"
+       visible="false"
+       image_name="AccountLevel_Plus"
+       layout="topleft"
+       right="-1"
+       top_delta="0"
+       mouse_opaque="false"
+       name="account_type_plus"
+       width="14" />
+      <text
+       font="SansSerifSmall"
+       text_color="White_50"
+       width="175"
+       follows="top|left|right"
+       layout="topleft"
+       mouse_opaque="false"
+       type="string"
+       height="16"
+       length="1"
+       left="129"
+       name="rezday"
+       top_pad="0" >
+        (Unknown)
+      </text>
+      <text
+       font="SansSerifSmall"
+       text_color="White_50"
+       width="175"
+       follows="top|left|right"
+       layout="topleft"
+       mouse_opaque="false"
+       type="string"
+       height="48"
+       length="1"
+       left_delta="0"
+       name="account_info"
+       top_pad="2" />
+      <text
+       font="SansSerifSmall"
+       text_color="White_50"
+       width="175"
+       follows="top|left|right"
+       layout="topleft"
+       mouse_opaque="false"
+       type="string"
+       height="16"
+       length="1"
+       left_delta="0"
+       name="partner_label"
+       top_pad="2">
+        Partner:
+      </text>
+      <text
+       font="SansSerifSmall"
+       text_color="White_50"
+       width="175"
+       follows="top|left|right"
+       layout="topleft"
+       mouse_opaque="false"
+       type="string"
+       height="16"
+       length="1"
+       left_delta="0"
+       name="partner_info"
+       top_pad="2">
+        secondlife:///app/agent/00000000-0000-0000-0000-000000000000/inspect
+      </text>
+    </layout_panel>
+    <layout_panel
+      name="avatar_desc"
+      follows="top|left|right"
+      top_pad="1"
+      left="0"
+      height="125"
+      width="304"
+      auto_resize="true"
+      layout="topleft">
+      <text_editor
+       type="string"
+       follows="all"
+       left="3"
+       layout="topleft"
+       max_length="65000"
+       name="sl_about"
+       top="0"
+       bottom="-20"
+       right="-4"
+       bg_readonly_color="DkGray2"
+       text_readonly_color="White"
+       commit_on_focus_lost="true"
+       word_wrap="true" 
+	   show_emoji_helper="true" />
+      <text
+       font="SansSerifSmall"
+       text_color="White_50"
+       follows="bottom|left|right"
+       layout="topleft"
+       mouse_opaque="false"
+       type="string"
+       height="16"
+       length="1"
+       left="3"
+       right="-4"
+       name="www"
+       top_pad="2" />
+      <line_editor
+        top_delta="-2"
+        follows="left|bottom|right"
+        layout="topleft"
+        height="20"
+        max_length_chars="254"
+        left="2"
+        right="-4"
+        text_pad_left="5"
+        tool_tip="Website link"
+        name="www_edit">
+        <line_editor.commit_callback
+          function="Profile.CommitProperties" />
+      </line_editor>
+    </layout_panel>
+    <layout_panel
+      visible="true"
+      name="avatar_perm"
+      follows="top|left|right"
+      top_pad="1"
+      left="0"
+      height="74"
+      width="304"
+      auto_resize="false"
+      layout="topleft">
+      <text
+       font="SansSerifSmall"
+       text_color="White_50"
+       width="190"
+       follows="top|left"
+       layout="topleft"
+       mouse_opaque="false"
+       type="string"
+       height="16"
+       length="1"
+       left="3"
+       name="permissions_label"
+       top_pad="2">
+        Allow this avatar to:
+      </text>
+      <check_box
+       height="16"
+       initial_value="false"
+       label="See when I am online"
+       layout="topleft"
+       top_pad="4"
+       left="5"
+       name="allow_show_online"
+       width="150">
+        <check_box.commit_callback
+         function="Profile.CommitRights" />
+      </check_box>
+      <check_box
+       height="16"
+       initial_value="false"
+       label="Find me on the world map"
+       layout="topleft"
+       top_pad="2"
+       name="allow_mapping"
+       width="150">
+        <check_box.commit_callback
+         function="Profile.CommitRights" />
+      </check_box>
+      <check_box
+       height="16"
+       initial_value="false"
+       label="Edit, delete, or take my objects"
+       layout="topleft"
+       top_pad="2"
+       name="allow_object_perms"
+       width="150">
+        <check_box.commit_callback
+         function="Profile.CommitModifyObjectRights" />
+      </check_box>
+    </layout_panel>
+    <layout_panel
+      visible="false"
+      name="avatar_in_search"
+      follows="top|left|right"
+      top_pad="1"
+      left="0"
+      height="18"
+      width="304"
+      auto_resize="false"
+      layout="topleft">
+      <check_box
+       height="16"
+       initial_value="true"
+       label="Show in search"
+       layout="topleft"
+       top_pad="0"
+       left="5"
+       name="allow_publish"
+       width="150">
+        <check_box.commit_callback
+         function="Profile.CommitProperties" />
+      </check_box>
+    </layout_panel>
+  </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml b/indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8d4a3a2e504acf80ff2ace8a320d6f6e3e3db52f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_legacy_sidetray.xml
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bg_opaque_color="PanelDefaultBackgroundColor"
+ background_opaque="true"
+ background_visible="true"
+ follows="all"
+ height="570"
+ label="Profile"
+ layout="topleft"
+ min_height="350"
+ left="0"
+ top="20"
+ name="Avatar Profile"
+ width="313">
+  <panel.string
+   name="account_info_fmt">
+[ACCOUNT_TYPE]
+[PAYMENT_INFO]
+[AGE_VERIFIED]
+  </panel.string>
+  <panel.string
+   name="age_verified">
+Age Verified
+  </panel.string>
+  <panel.string
+   name="rezday_fmt">
+[REZDAY] ([AGE])
+  </panel.string>
+  <panel.string
+   name="add_friend">
+Add Friend
+  </panel.string>
+  <panel.string
+   name="remove_friend">
+Remove Friend
+  </panel.string>
+  <panel
+   name="avatar_info_top"
+   bg_opaque_color="PanelDefaultBackgroundColor"
+   background_visible="true"
+   background_opaque="true"
+   follows="top|left|right"
+   top="0"
+   left="0"
+   height="29"
+   width="313"
+   layout="topleft">
+    <button
+     follows="top|left"
+     height="24"
+     image_hover_unselected="BackButton_Over"
+     image_pressed="BackButton_Press"
+     image_unselected="BackButton_Off"
+     layout="topleft"
+     name="back"
+     left="7"
+     tab_stop="false"
+     top="2"
+     width="30"
+     use_draw_context_alpha="false" />
+    <text_editor
+     allow_scroll="false"
+     bg_visible="false"
+     read_only="true"
+     layout="topleft"
+     name="avatar_name"
+     v_pad="0"
+     value="(Loading...)"
+     font="SansSerifHugeBold"
+     h_pad="0"
+     height="26"
+     left_pad="8"
+     text_color="LtGray"
+     top="1"
+     use_ellipses="true"
+     width="268"
+     follows="top|left|right"
+     word_wrap="false"
+     mouse_opaque="false"/>
+    <loading_indicator
+     height="25"
+     follows="top|right"
+     layout="topleft"
+     left_pad="-32"
+     name="progress_indicator"
+     top_delta="1"
+     width="25" />
+  </panel>
+  <layout_stack
+   name="layout"
+   orientation="vertical"
+   follows="all"
+   left="6"
+   top_pad="0"
+   height="506"
+   width="302"
+   border_size="0">
+    <layout_panel
+     bg_opaque_color="PanelDefaultBackgroundColor"
+     background_visible="true"
+     background_opaque="true"
+     name="avatar_accordions"
+     follows="all"
+     layout="topleft"
+     auto_resize="true"
+     user_resize="true"
+     height="513"
+     width="313">
+      <accordion
+       left="0"
+       top="0"
+       single_expansion="true"
+       fit_parent="true"
+       follows="all"
+       layout="topleft"
+       name="avatar_accordion"
+       height="513"
+       width="313">
+        <accordion_tab
+         expanded="true"
+         layout="topleft"
+         name="avatar_secondlife_tab"
+         title="Second Life"
+         fit_panel="true">
+          <panel
+           border="false"
+           filename="panel_profile_legacy_secondlife.xml"
+           layout="topleft"
+           left="0"
+           follows="all"
+           name="avatar_secondlife_tab_panel"
+           top="0" />
+        </accordion_tab>
+        <accordion_tab
+         expanded="false"
+         layout="topleft"
+         name="avatar_groups_tab"
+         title="Groups"
+         fit_panel="true">
+          <panel
+           border="false"
+           class="panel_profile_legacy_groups"
+           filename="panel_profile_legacy_groups.xml"
+           follows="all"
+           layout="topleft"
+           left="0"
+           name="avatar_groups_tab_panel"
+           top="0" />
+        </accordion_tab>
+        <accordion_tab
+         expanded="false"
+         layout="topleft"
+         name="avatar_picks_tab"
+         title="Picks"
+         fit_panel="true">
+          <panel
+           border="false"
+           class="panel_profile_legacy_picks"
+           filename="panel_profile_legacy_picks.xml"
+           follows="all"
+           layout="topleft"
+           left="0"
+           name="avatar_picks_tab_panel"
+           top="0" />
+        </accordion_tab>
+        <accordion_tab
+         expanded="false"
+         layout="topleft"
+         name="avatar_firstlife_tab"
+         title="First Life"
+         fit_panel="true">
+          <panel
+           border="false"
+           filename="panel_profile_legacy_firstlife.xml"
+           follows="left|top|right"
+           layout="topleft"
+           left="0"
+           name="avatar_firstlife_tab_panel"
+           top="0" />
+        </accordion_tab>
+        <accordion_tab
+         expanded="false"
+         layout="topleft"
+         name="avatar_notes_tab"
+         title="Notes"
+         fit_panel="true">
+          <panel
+           border="false"
+           filename="panel_profile_legacy_notes.xml"
+           follows="all"
+           layout="topleft"
+           left="0"
+           name="avatar_notes_tab_panel"
+           top="0" />
+        </accordion_tab>
+      </accordion>
+    </layout_panel>
+  </layout_stack>
+
+  <layout_stack
+   follows="bottom|left|right"
+   height="25"
+   layout="topleft"
+   name="button_row_ls"
+   left="6"
+   orientation="horizontal"
+   top_pad="5"
+   width="299">
+    <layout_panel
+     follows="bottom|left|right"
+     height="23"
+     layout="bottomleft"
+     left="0"
+     name="btn_chat_lp"
+     auto_resize="true"
+     width="91">
+      <button
+       follows="bottom|left|right"
+       left="1"
+       height="23"
+       name="btn_chat"
+       label="Chat"
+       layout="topleft"
+       tool_tip="Send an instant message"
+       top="0"
+       width="90">
+        <button.commit_callback
+         function="Profile.Action"
+         parameter="chat" />
+      </button>
+    </layout_panel>
+    <layout_panel
+     follows="bottom|left|right"
+     height="23"
+     layout="bottomleft"
+     left_pad="3"
+     name="btn_friend_lp"
+     auto_resize="true"
+     width="91">
+      <button
+       follows="bottom|left|right"
+       left="1"
+       height="23"
+       name="btn_friend"
+       label="Add Friend"
+       layout="topleft"
+       top="0"
+       width="90">
+        <button.commit_callback
+         function="Profile.Action"
+         parameter="friend" />
+      </button>
+    </layout_panel>
+    <layout_panel
+     follows="bottom|left|right"
+     height="23"
+     layout="bottomleft"
+     left_pad="3"
+     name="btn_block_lp"
+     auto_resize="true"
+     width="91">
+      <button
+       follows="bottom|left|right"
+       left="1"
+       height="23"
+       name="btn_block"
+       label="Block"
+       layout="topleft"
+       tool_tip="Block this avatar"
+       top="0"
+       width="90">
+        <button.commit_callback
+         function="Profile.Action"
+         parameter="block" />
+      </button>
+    </layout_panel>
+    <layout_panel
+     follows="bottom|left|right"
+     height="23"
+     layout="bottomleft"
+     left_pad="3"
+     name="btn_menu_lp"
+     auto_resize="false"
+     width="30">
+    <menu_button
+     follows="bottom|left|right"
+     height="23"
+     image_hover_unselected="Toolbar_Middle_Over"
+     image_overlay="OptionsMenu_Off"
+     image_selected="Toolbar_Middle_Selected"
+     image_unselected="Toolbar_Middle_Off"
+     menu_filename="menu_profile_legacy.xml"
+     menu_position="bottomleft"
+     tool_tip="Actions on this avatar"
+     layout="topleft"
+     left="1"
+     top="0"
+     name="btn_menu"
+     width="30" />
+    </layout_panel>
+  </layout_stack>
+  <drop_target
+   top="0"
+   bottom="-1"
+   left="0"
+   right="-1"
+   layout="topleft"
+   follows="all"
+   name="drop_target"
+   mouse_opaque="false" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_search_classifieds.xml b/indra/newview/skins/default/xui/en/panel_search_classifieds.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a865121b618f1e72219ca92d89f24058d41cd9cd
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_search_classifieds.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="70"
+ layout="topleft"
+ name="panel_search_classifieds"
+ width="602"
+ default_tab_group="2">
+  <text
+   follows="left|top|right"
+   height="16"
+   layout="topleft"
+   left="4"
+   name="search_title"
+   top="4"
+   value="Enter search terms:"
+   width="255" />
+  <check_box
+   control_name="ShowPGClassifieds"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left="489"
+   name="pg_all"
+   top="4"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_PG_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_general"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowMatureClassifieds"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="mature_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_M_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_moderate"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowAdultClassifieds"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="adult_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_R_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_adult"
+   top_delta="-1"
+   width="18"/>
+  <search_editor
+   tab_group="2"
+   follows="top|left|right"
+   search_button_visible="true"
+   height="22"
+   text_readonly_color="DkGray"
+   label="Search"
+   layout="topleft"
+   top_pad="1"
+   left="4"
+   right="-128"
+   name="search_bar"
+   select_on_focus="true"
+   commit_on_focus_lost="false"
+   tool_tip="Enter search terms">
+    <search_editor.commit_callback
+     function="Search.query" />
+  </search_editor>
+  <combo_box
+   follows="right|top"
+   layout="topleft"
+   height="23"
+   allow_text_entry="false"
+   top_delta="0"
+   left_pad="2"
+   name="classifieds_category"
+   width="122">
+    <combo_box.commit_callback
+     function="Search.query" />
+  </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_search_events.xml b/indra/newview/skins/default/xui/en/panel_search_events.xml
new file mode 100644
index 0000000000000000000000000000000000000000..407eaf6486a0fc4d24a03b249002f89c7274f1fe
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_search_events.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="70"
+ layout="topleft"
+ name="panel_search_events"
+ width="602"
+ default_tab_group="2">
+  <text
+   follows="left|top"
+   height="16"
+   layout="topleft"
+   left="4"
+   name="search_title"
+   top="4"
+   value="Enter search terms:"
+   width="128" />
+  <radio_group
+   top_delta="0"
+   left="130"
+   height="16"
+   width="230"
+   layout="topleft"
+   initial_value="current"
+   name="events_search_mode">
+    <radio_item
+     height="16"
+     label="Ongoing and Upcoming"
+     layout="topleft"
+     name="current"
+     value="current"
+     top_pad="0"
+     width="120" />
+    <radio_item
+     height="16"
+     label="By Date"
+     layout="topleft"
+     name="date"
+     value="date"
+     left_pad="40"
+     width="120" />
+    <radio_group.commit_callback
+     function="Search.query" />
+  </radio_group>
+  <button
+   follows="top|left"
+   height="16"
+   width="16"
+   image_unselected="MinusItem_Off"
+   image_disabled="MinusItem_Disabled"
+   image_selected="MinusItem_Press"
+   image_pressed="MinusItem_Press"
+   image_top_pad="0"
+   layout="topleft"
+   left_pad="14"
+   name="minus_day"
+   top_delta="0">
+    <button.commit_callback
+     function="Search.MinusDay" />
+  </button>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   top_delta="0"
+   layout="topleft"
+   left_pad="5"
+   name="events_date"
+   font.style="BOLD"
+   height="16"
+   width="40"
+   value="4/20" />
+  <button
+   follows="top|left"
+   height="16"
+   width="16"
+   image_unselected="AddItem_Off"
+   image_disabled="AddItem_Disabled"
+   image_selected="AddItem_Press"
+   image_pressed="AddItem_Press"
+   image_top_pad="0"
+   layout="topleft"
+   left_pad="5"
+   name="plus_day"
+   top_delta="0">
+    <button.commit_callback
+     function="Search.AddDay" />
+  </button>
+  <check_box
+   control_name="ShowPGEvents"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left="489"
+   name="pg_all"
+   top="4"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_PG_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_general"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowMatureEvents"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="mature_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_M_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_moderate"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowAdultEvents"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="adult_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_R_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_adult"
+   top_delta="-1"
+   width="18"/>
+  <search_editor
+   tab_group="2"
+   follows="top|left|right"
+   search_button_visible="true"
+   height="22"
+   text_readonly_color="DkGray"
+   label="Search"
+   layout="topleft"
+   top_pad="1"
+   left="4"
+   right="-128"
+   name="search_bar"
+   select_on_focus="true"
+   commit_on_focus_lost="false"
+   tool_tip="Enter search terms">
+    <search_editor.commit_callback
+     function="Search.query" />
+  </search_editor>
+  <combo_box
+   follows="right|top"
+   layout="topleft"
+   height="23"
+   allow_text_entry="false"
+   top_delta="0"
+   left_pad="2"
+   name="events_category"
+   width="122">
+    <combo_box.item label="Any Category" name="any" value="0" />
+    <combo_box.item label="" value="filter_separator" enabled="false" />
+    <combo_box.item label="Discussion" name="discussion" value="18" />
+    <combo_box.item label="Sports" name="sports" value="19" />
+    <combo_box.item label="Live Music" name="music" value="20" />
+    <!-- <combo_box.item label="???" name="mystery_category" value="21" /> -->
+    <combo_box.item label="Commercial" name="commercial" value="22" />
+    <combo_box.item label="Nightlife/Entertainment" name="nightlife" value="23" />
+    <combo_box.item label="Games/Contests" name="games" value="24" />
+    <combo_box.item label="Pageants" name="pageants" value="25" />
+    <combo_box.item label="Education" name="education" value="26" />
+    <combo_box.item label="Arts and Culture" name="arts" value="27" />
+    <combo_box.item label="Charity/Support Groups" name="charity" value="28" />
+    <combo_box.item label="Miscellaneous" name="misc" value="29" />
+    <combo_box.commit_callback
+     function="Search.query" />
+  </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_search_groups.xml b/indra/newview/skins/default/xui/en/panel_search_groups.xml
new file mode 100644
index 0000000000000000000000000000000000000000..78e531ca2fc354161acaa5df8039b58f59b9fb58
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_search_groups.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="70"
+ layout="topleft"
+ name="panel_search_groups"
+ width="602"
+ default_tab_group="2">
+  <text
+   follows="left|top|right"
+   height="16"
+   layout="topleft"
+   left="4"
+   name="search_title"
+   top="4"
+   value="Enter search terms:"
+   width="255" />
+  <check_box
+   control_name="ShowPGGroups"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left="489"
+   name="pg_all"
+   top="4"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_PG_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_general"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowMatureGroups"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="mature_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_M_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_moderate"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowAdultGroups"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="adult_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_R_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_adult"
+   top_delta="-1"
+   width="18"/>
+  <search_editor
+   tab_group="2"
+   follows="top|left|right"
+   search_button_visible="true"
+   height="22"
+   text_readonly_color="DkGray"
+   label="Search"
+   layout="topleft"
+   top_pad="1"
+   left="4"
+   right="-4"
+   name="search_bar"
+   select_on_focus="true"
+   commit_on_focus_lost="false"
+   tool_tip="Enter search terms">
+    <search_editor.commit_callback
+     function="Search.query" />
+  </search_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_search_landsales.xml b/indra/newview/skins/default/xui/en/panel_search_landsales.xml
new file mode 100644
index 0000000000000000000000000000000000000000..982fcdefc9db9a7f7b13f0dcce8582965dc748ab
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_search_landsales.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="70"
+ layout="topleft"
+ name="panel_search_landsales"
+ width="602">
+  <text
+   follows="left|top|right"
+   height="16"
+   layout="topleft"
+   left="4"
+   name="search_title"
+   top="4"
+   value="Enter search terms:"
+   width="255" />
+  <check_box
+   control_name="ShowPGLand"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left="489"
+   name="pg_all"
+   top="4"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_PG_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_general"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowMatureLand"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="mature_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_M_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_moderate"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowAdultLand"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="adult_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_R_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_adult"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="FindLandPrice"
+   follows="left|top"
+   height="16"
+   label="Price &lt;"
+   layout="topleft"
+   left="4"
+   name="price_check"
+   top_pad="6"
+   width="40" >
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <line_editor
+   enabled_control="FindLandPrice"
+   commit_on_focus_lost="false"
+   follows="left|top"
+   height="16"
+   left_pad="20"
+   name="edit_price"
+   layout="topleft"
+   top_delta="-1"
+   width="40" >
+    <line_editor.commit_callback
+     function="Search.query" />
+  </line_editor>
+  <check_box
+   control_name="FindLandArea"
+   follows="left|top"
+   height="16"
+   label="Area &gt;"
+   layout="topleft"
+   left_pad="3"
+   name="area_check"
+   top_delta="1"
+   width="40" >
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <line_editor
+   enabled_control="FindLandArea"
+   commit_on_focus_lost="false"
+   follows="left|top"
+   layout="topleft"
+   height="16"
+   left_pad="18"
+   name="edit_area"
+   top_delta="-1"
+   width="40" >
+    <line_editor.commit_callback
+     function="Search.query" />
+  </line_editor>
+  <combo_box
+   control_name="FindLandType"
+   follows="right|top"
+   layout="topleft"
+   height="22"
+   allow_text_entry="false"
+   left_pad="90"
+   top_delta="-1"
+   name="land_type"
+   width="110">
+    <combo_box.item label="All Categories" name="All" value="All"/>
+    <combo_box.item label="Auction" name="Auction" value="Auction"/>
+    <combo_box.item label="Mainland Sales" name="Mainland" value="Mainland"/>
+    <combo_box.item label="Estate Sales" name="Estate" value="Estate"/>
+    <combo_box.commit_callback
+     function="Search.query" />
+  </combo_box>
+  <combo_box
+   control_name="FindLandSort"
+   follows="right|top"
+   layout="topleft"
+   height="22"
+   allow_text_entry="false"
+   left_pad="2"
+   top_delta="0"
+   name="land_sort"
+   width="110">
+    <combo_box.item label="Sort by Name" name="Name_item" value="Name"/>
+    <combo_box.item label="Sort by Price" name="Price_item" value="Price"/>
+    <combo_box.item label="Sort by Price per meter" name="PPM_item" value="PPM"/>
+    <combo_box.item label="Sort by Area" name="Area_item" value="Area"/>
+    <combo_box.commit_callback
+     function="Search.query" />
+  </combo_box>
+  <check_box
+   control_name="FindLandSortAscending"
+   follows="right|top"
+   height="16"
+   label="Ascending"
+   layout="topleft"
+   left_pad="3"
+   name="ascending"
+   top_delta="5"
+   width="40" >
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_search_people.xml b/indra/newview/skins/default/xui/en/panel_search_people.xml
new file mode 100644
index 0000000000000000000000000000000000000000..98387dbd9a2f18aada111dbf62fa904008499c05
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_search_people.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="70"
+ class="panel_search_people"
+ name="panel_search_people"
+ width="602"
+ default_tab_group="2">
+  <panel.string name="SeachFilteredOnShortWordsEmpty">
+   Your search terms were too short so no search was performed.
+  </panel.string>
+  <text
+   follows="left|top|right"
+   height="16"
+   layout="topleft"
+   left="4"
+   name="search_title"
+   top="4"
+   value="Enter search terms:"
+   width="255" />
+  <search_editor
+   tab_group="2"
+   follows="top|left|right"
+   search_button_visible="true"
+   height="22"
+   text_readonly_color="DkGray"
+   label="Search"
+   layout="topleft"
+   top_pad="1"
+   left="4"
+   right="-4"
+   name="search_bar"
+   select_on_focus="true"
+   commit_on_focus_lost="false"
+   tool_tip="Enter search terms">
+    <search_editor.commit_callback
+     function="Search.query" />
+  </search_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_search_places.xml b/indra/newview/skins/default/xui/en/panel_search_places.xml
new file mode 100644
index 0000000000000000000000000000000000000000..94ae80a1576933b64eeae4bd6547b57632c96921
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_search_places.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="70"
+ layout="topleft"
+ name="panel_search_places"
+ width="602"
+ default_tab_group="2">
+  <text
+   follows="left|top|right"
+   height="16"
+   layout="topleft"
+   left="4"
+   name="search_title"
+   top="4"
+   value="Enter search terms:"
+   width="255" />
+  <check_box
+   control_name="ShowPGSims"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left="489"
+   name="pg_all"
+   top="4"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_PG_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_general"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowMatureSims"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="mature_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_M_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_moderate"
+   top_delta="-1"
+   width="18"/>
+  <check_box
+   control_name="ShowAdultSims"
+   follows="right|top"
+   height="16"
+   label=""
+   layout="topleft"
+   left_pad="2"
+   name="adult_all"
+   top_delta="1"
+   width="15">
+    <check_box.commit_callback
+     function="Search.query" />
+  </check_box>
+  <icon
+   follows="right|top"
+   height="16"
+   image_name="Parcel_R_Dark"
+   layout="topleft"
+   left_pad="2"
+   name="rating_icon_adult"
+   top_delta="-1"
+   width="18"/>
+  <search_editor
+   tab_group="2"
+   follows="top|left|right"
+   search_button_visible="true"
+   height="22"
+   text_readonly_color="DkGray"
+   label="Search"
+   layout="topleft"
+   top_pad="1"
+   left="4"
+   right="-128"
+   name="search_bar"
+   select_on_focus="true"
+   commit_on_focus_lost="false"
+   tool_tip="Enter search terms">
+    <search_editor.commit_callback
+     function="Search.query" />
+  </search_editor>
+  <combo_box
+   follows="right|top"
+   layout="topleft"
+   height="23"
+   allow_text_entry="false"
+   top_delta="0"
+   left_pad="2"
+   name="places_category"
+   width="122">
+    <combo_box.commit_callback
+     function="Search.query" />
+  </combo_box>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_search_web.xml b/indra/newview/skins/default/xui/en/panel_search_web.xml
new file mode 100644
index 0000000000000000000000000000000000000000..81cb9067db204685ce625dbfae92b9b87c36d1b9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_search_web.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="775"
+ layout="topleft"
+ follows="all"
+ name="panel_search_web"
+ width="780"
+ default_tab_group="2">
+  <layout_stack
+    bottom="775"
+    follows="all"
+    layout="topleft"
+    left="5"
+    animate="false"
+    name="stack1"
+    orientation="vertical"
+    top="4"
+    width="770">
+    <layout_panel
+      height="40"
+      follows="all"
+      layout="topleft"
+      left_delta="0"
+      name="external_controls"
+      top_delta="0"
+      auto_resize="true"
+      width="585">
+      <web_browser
+        tab_group="2"
+        bottom="-2"
+        follows="all"
+        layout="topleft"
+        left="0"
+        name="webbrowser"
+        top="0"/>
+    </layout_panel>
+    <layout_panel
+     name="status_bar"
+     height="23"
+     auto_resize="false">
+      <button
+       image_overlay="Arrow_Left_Off"
+       image_disabled="PushButton_Disabled"
+       image_disabled_selected="PushButton_Disabled"
+       image_selected="PushButton_Selected"
+       image_unselected="PushButton_Off"
+       chrome="true"
+       hover_glow_amount="0.15"
+       tool_tip="Navigate back"
+       follows="left|top"
+       height="22"
+       layout="topleft"
+       left="1"
+       name="back"
+       top="0"
+       width="22">
+        <button.commit_callback
+         function="WebContent.Back" />
+      </button>
+      <button
+       image_overlay="Arrow_Right_Off"
+       image_disabled="PushButton_Disabled"
+       image_disabled_selected="PushButton_Disabled"
+       image_selected="PushButton_Selected"
+       image_unselected="PushButton_Off"
+       chrome="true"
+       tool_tip="Navigate forward"
+       follows="left|top"
+       height="22"
+       layout="topleft"
+       left="27"
+       name="forward"
+       top_delta="0"
+       width="22">
+        <button.commit_callback
+         function="WebContent.Forward" />
+      </button>
+      <button
+       image_overlay="Stop_Off"
+       image_disabled="PushButton_Disabled"
+       image_disabled_selected="PushButton_Disabled"
+       image_selected="PushButton_Selected"
+       image_unselected="PushButton_Off"
+       chrome="true"
+       tool_tip="Stop navigation"
+       enabled="true"
+       follows="left|top"
+       height="22"
+       layout="topleft"
+       left="51"
+       name="stop"
+       top_delta="0"
+       width="22">
+        <button.commit_callback
+         function="WebContent.Stop" />
+      </button>
+      <button
+       image_overlay="Refresh_Off"
+       image_disabled="PushButton_Disabled"
+       image_disabled_selected="PushButton_Disabled"
+       image_selected="PushButton_Selected"
+       image_unselected="PushButton_Off"
+       chrome="true"
+       tool_tip="Reload page"
+       follows="left|top"
+       height="22"
+       layout="topleft"
+       left="51"
+       name="reload"
+       top_delta="0"
+       width="22">
+        <button.commit_callback
+         function="WebContent.Reload" />
+      </button>
+      <text
+       type="string"
+       length="200"
+       follows="bottom|left"
+       height="20"
+       layout="topleft"
+       left_pad="3"
+       name="statusbartext"
+       parse_urls="false"
+       text_color="0.4 0.4 0.4 1"
+       top_delta="1"
+       width="441"/>
+      <progress_bar
+       color_bar="0.3 1.0 0.3 1"
+       follows="bottom|right"
+       height="16"
+       top_delta="1"
+       left_pad="3"
+       layout="topleft"
+       name="statusbarprogress"
+       width="64"/>
+    </layout_panel>
+  </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 1ac155b9e6fc1aeb9bf3f551aedf822b042f3234..6830a39a2aa9f423d2505d3da6323157b5134c49 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2995,13 +2995,13 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .anim
 	<string name="None">None</string>
 	<string name="Linden Location">Linden Location</string>
 	<string name="Adult">Adult</string>
-	<string name="Arts and Culture">Arts &amp; Culture</string>
+	<string name="Arts&amp;Culture">Arts &amp; Culture</string>
 	<string name="Business">Business</string>
 	<string name="Educational">Educational</string>
 	<string name="Gaming">Gaming</string>
 	<string name="Hangout">Hangout</string>
 	<string name="Newcomer Friendly">Newcomer Friendly</string>
-	<string name="Parks and Nature">Parks &amp; Nature</string>
+	<string name="Parks&amp;Nature">Parks &amp; Nature</string>
 	<string name="Residential">Residential</string>
 	<!--<string name="Shopping">Shopping</string>	-->
 	<string name="Stage">Stage</string>
@@ -4470,13 +4470,6 @@ and report the problem.
   <string name="outfit_photo_load_codec_error">Invalid image format. Please use another image</string>
 
   <!-- Alchemy Strings -->
-  <string name="not_found">&apos;[TEXT]&apos; not found</string>
-  <string name="no_results">No results</string>
-  <string name="searching">Searching...</string>
-  <string name="all_categories">All Categories</string>
-  <string name="search_banned">Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards.</string>
-  <string name="search_short">Your search terms were too short so no search was performed.</string>
-  <string name="search_disabled">Legacy Search has been disabled in this region.</string>
   <string name="NotifyIncomingMessage">Incoming message from [NAME]...</string>
   <string name="NearbyChatTitleChannel">Nearby chat (on channel [CHANNEL])</string>
   <string name="AvatarTyping">Typing</string>
diff --git a/indra/newview/skins/heretic/colors.xml b/indra/newview/skins/heretic/colors.xml
index f97407cd628562e4a1b51bd195da644ac8157b60..19b8501e24888ff799b145df1dae0067da4482a6 100644
--- a/indra/newview/skins/heretic/colors.xml
+++ b/indra/newview/skins/heretic/colors.xml
@@ -1155,6 +1155,9 @@
   <color
    name="StatBarMeanBarColor"
    reference="Red_80" />
+  <color
+   name="ProfileOnlineIndicatorColor"
+   reference="Green" />
    <color
     name="MusicTickerGridColor" 
     reference="White_50"/>