diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f7d81446bb53a83a7a4e8157f8144ee9ffea61cf..53159825f39ffa1e79f6537b51d7e4c6491959aa 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -139,6 +139,7 @@ set(viewer_SOURCE_FILES
     altoolalign.cpp
     alunzip.cpp
     alviewermenu.cpp
+    fsfloatersearch.cpp
     groupchatlistener.cpp
     llagentwearablesfetch.cpp
     llaccountingcostmanager.cpp
@@ -815,6 +816,7 @@ set(viewer_HEADER_FILES
     altoolalign.h
     alunzip.h
     alviewermenu.h
+    fsfloatersearch.h
     groupchatlistener.h
     llaccountingcost.h
     llagentwearablesfetch.h
diff --git a/indra/newview/app_settings/settings_alchemy.xml b/indra/newview/app_settings/settings_alchemy.xml
index 43cdcf2118157aa4b1833eb427320cddbd0f8f1b..7d900f47137656a0cee98bbb36f0ff0cb2282786 100644
--- a/indra/newview/app_settings/settings_alchemy.xml
+++ b/indra/newview/app_settings/settings_alchemy.xml
@@ -962,5 +962,27 @@
       <key>Value</key>
       <string>8dcd4a48-2d37-4909-9f78-f7a9eb4ef903</string>
     </map>
+    <key>FSLastSearchTab</key>
+    <map>
+		<key>Comment</key>
+		<string>Last selected tab in search window</string>
+		<key>Persist</key>
+		<integer>1</integer>
+		<key>Type</key>
+		<string>S32</string>
+		<key>Value</key>
+		<integer>0</integer>
+    </map>
+    <key>FSLegacySearchActionOnTeleport</key>
+    <map>
+        <key>Comment</key>
+        <string>Controls what action Legacy Search should take when teleporting: 0 = No effect, 1 = Close floater, 2 Minimise floater</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>U32</string>
+        <key>Value</key>
+        <integer>1</integer>
+    </map>
   </map>
 </llsd>
diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..849adf3174d1786904f4a4d904de05f5de1b41ac
--- /dev/null
+++ b/indra/newview/fsfloatersearch.cpp
@@ -0,0 +1,3153 @@
+/**
+ * @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 "llpanelclassified.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 (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);
+			}
+		}
+		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(&LLPanelClassifiedInfo::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());
+
+		LLPanelClassifiedInfo::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);
+}
+
+FSFloaterSearch::~FSFloaterSearch()
+{
+	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
+	{
+		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(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);
+	}
+}
+
+void FSFloaterSearch::displayEventDetails(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName, const std::string &eventDesc, const std::string &simName, U32 eventDuration, U32 eventFlags, U32 eventCover, LLVector3d eventGlobalPos)
+{
+	if (eventFlags == EVENT_FLAG_ADULT)
+	{
+		mDetailMaturity->setValue("Parcel_R_Dark");
+	}
+	else if (eventFlags == 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(eventGlobalPos.mdV[VX]) % REGION_WIDTH_UNITS;
+	region_y = (S64)ll_round(eventGlobalPos.mdV[VY]) % REGION_WIDTH_UNITS;
+	region_z = (S32)ll_round(eventGlobalPos.mdV[VZ]);
+	LLStringUtil::format_map_t map;
+	map["DURATION"] = llformat("%d:%.2d", eventDuration / 60, eventDuration % 60);
+	map["LOCATION"] = llformat("%s (%d, %d, %d)", simName.c_str(), region_x, region_y, region_z);
+	if (eventCover > 0)
+	{
+		map["COVERCHARGE"] = llformat("L$%d", eventCover);
+		mDetailAux2->setValue(getString("string.covercharge", map));
+	}
+
+	mParcelGlobal = eventGlobalPos;
+	mEventID = eventId;
+	mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_events");
+	mHasSelection = true;
+	mDetailMaturity->setVisible(true);
+	mDetailTitle->setValue(eventName);
+	mDetailDesc->setValue(eventDesc);
+	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(simName, boost::bind(&FSFloaterSearch::regionHandleCallback, this, _1, eventGlobalPos), "", false);
+}
+
+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);
+
+	// 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());
+	}
+	// for OpenSim, do the same as in earlier versions
+	else
+	{
+		std::string debug_url = gSavedSettings.getString("SearchURLDebug");
+		if (gSavedSettings.getBOOL("DebugSearch") && !debug_url.empty())
+		{
+			url = debug_url;
+		}
+	}
+
+	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
new file mode 100644
index 0000000000000000000000000000000000000000..2b6a3055c890d314cfd79de95f4975b3017c1598
--- /dev/null
+++ b/indra/newview/fsfloatersearch.h
@@ -0,0 +1,416 @@
+/**
+ * @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"
+
+class FSSearchRemoteParcelInfoObserver;
+class LLAvatarPropertiesObserver;
+class LLGroupMgrObserver;
+class LLSearchEditor;
+class LLSearchComboBox;
+class FSFloaterSearch;
+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;
+
+	FSFloaterSearch*		mParent;
+	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;
+
+	FSFloaterSearch*	mParent;
+	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;
+
+	FSFloaterSearch*	mParent;
+	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;
+
+	FSFloaterSearch*	mParent;
+	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;
+
+	FSFloaterSearch*	mParent;
+	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;
+
+	FSFloaterSearch*	mParent;
+	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);
+	void displayEventDetails(U32 eventId,
+							 F64 eventEpoch,
+							 const std::string& eventDateStr,
+							 const std::string &eventName,
+							 const std::string &eventDesc,
+							 const std::string &simName,
+							 U32 eventDuration,
+							 U32 eventFlags,
+							 U32 eventCover,
+							 LLVector3d eventGlobalPos);
+	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;
+
+	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/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index 987b0a7efa4a18cff6c15a99db9174d1388d9dca..2c812bad67e498991f9daa9290255cb10541eca3 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -380,6 +380,8 @@ void LLAvatarPropertiesProcessor::processClassifiedInfoReply(LLMessageSystem* ms
 	// Request processed, no longer pending
 	self->removePendingRequest(c_info.creator_id, APT_CLASSIFIED_INFO);
 	self->notifyObservers(c_info.creator_id, &c_info, APT_CLASSIFIED_INFO);
+	self->removePendingRequest(c_info.classified_id, APT_CLASSIFIED_INFO);
+	self->notifyObservers(c_info.classified_id, &c_info, APT_CLASSIFIED_INFO);
 }
 
 
diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp
index 729fe93df7cecb26c47035f5966febda67394a2e..941f7cb7d0f136aa63d86244f941a4971739f553 100644
--- a/indra/newview/lleventnotifier.cpp
+++ b/indra/newview/lleventnotifier.cpp
@@ -44,7 +44,7 @@ class LLEventHandler : public LLCommandHandler
 	// requires trusted browser to trigger
 	LLEventHandler() : LLCommandHandler("event", UNTRUSTED_THROTTLE) { }
 	bool handle(const LLSD& params, const LLSD& query_map,
-				LLMediaCtrl* web)
+				LLMediaCtrl* web) override
 	{
 		if (params.size() < 2)
 		{
@@ -103,7 +103,7 @@ LLEventNotifier::~LLEventNotifier()
 
 	for (iter = mEventNotifications.begin();
 		 iter != mEventNotifications.end();
-		 iter++)
+		 ++iter)
 	{
 		delete iter->second;
 	}
@@ -124,7 +124,7 @@ void LLEventNotifier::update()
 		{
 			LLEventNotification *np = iter->second;
 
-			iter++;
+			++iter;
 			if (np->getEventDateEpoch() < alert_time)
 			{
 				LLSD args;
@@ -164,11 +164,12 @@ bool LLEventNotifier::handleResponse(U32 eventId, const LLSD& notification, cons
 	return true;
 }
 
-bool LLEventNotifier::add(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName)
+bool LLEventNotifier::add(const LLEventStruct& event)
 {
-	LLEventNotification *new_enp = new LLEventNotification(eventId, eventEpoch, eventDateStr, eventName);
+	if (mNewEventSignal(event)) return false;
+	LLEventNotification *new_enp = new LLEventNotification(event.eventId, event.eventEpoch, event.eventDateStr, event.eventName);
 	
-	LL_INFOS() << "Add event " << eventName << " id " << eventId << " date " << eventDateStr << LL_ENDL;
+	LL_INFOS() << "Add event " << event.eventName << " id " << event.eventId << " date " << event.eventDateStr << LL_ENDL;
 	if(!new_enp->isValid())
 	{
 		delete new_enp;
@@ -204,12 +205,23 @@ void LLEventNotifier::processEventInfoReply(LLMessageSystem *msg, void **)
 	U32 event_time_utc;
 	
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
-	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);
+	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);
 	
-	gEventNotifier.add(event_id, (F64)event_time_utc, eventd_date, event_name);
+	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);
+	
+	gEventNotifier.add(event);
 }	
 	
 	
@@ -247,11 +259,13 @@ void LLEventNotifier::load(const LLSD& event_options)
             substitution["datetime"] = date;
             LLStringUtil::format(dateStr, substitution);
 
-            add(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString());
+			LLEventStruct event(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString());
+            add(event);
         }
         else
         {
-            add(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString());
+			LLEventStruct event(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString());
+            add(event);
         }
 	}
 }
@@ -295,11 +309,11 @@ void LLEventNotifier::serverPushRequest(U32 event_id, bool add)
 }
 
 
-LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName) :
+LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, std::string eventDateStr, std::string eventName) :
 	mEventID(eventId),
-	mEventName(eventName),
+	mEventName(std::move(eventName)),
 	mEventDateEpoch(eventEpoch),
-    mEventDateStr(eventDateStr)
+    mEventDateStr(std::move(eventDateStr))
 {
 	
 }
diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h
index 3fee46c2f67a39832979db6cd74116b4bddcfb19..03c6785838bfcbac78dd513d694fa0578b2455f7 100644
--- a/indra/newview/lleventnotifier.h
+++ b/indra/newview/lleventnotifier.h
@@ -27,12 +27,31 @@
 #ifndef LL_LLEVENTNOTIFIER_H
 #define LL_LLEVENTNOTIFIER_H
 
+#include <utility>
 #include "llframetimer.h"
 #include "v3dmath.h"
 
 class LLEventNotification;
 class LLMessageSystem;
 
+typedef struct event_st{
+	U32 eventId = 0;
+	F64 eventEpoch = 0.0;
+	std::string eventDateStr;
+	std::string eventName;
+	std::string creator;
+	std::string category;
+	std::string desc;
+	U32 duration = 0;
+	U32 cover = 0;
+	U32 amount = 0;
+	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;
+} LLEventStruct;
 
 class LLEventNotifier
 {
@@ -41,7 +60,7 @@ class LLEventNotifier
 	virtual ~LLEventNotifier();
 
 	void update();	// Notify the user of the event if it's coming up
-	bool add(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName);
+	bool add(const LLEventStruct& event);
 	void add(U32 eventId);
 
 	
@@ -54,7 +73,14 @@ class LLEventNotifier
 	typedef std::map<U32, LLEventNotification *> en_map;
 	bool  handleResponse(U32 eventId, const LLSD& notification, const LLSD& response);		
 
-	static void processEventInfoReply(LLMessageSystem *msg, void **);	
+	static void processEventInfoReply(LLMessageSystem *msg, void **);
+	
+	typedef boost::signals2::signal<bool(LLEventStruct event)> new_event_signal_t;
+	new_event_signal_t mNewEventSignal;
+	boost::signals2::connection setNewEventCallback(const new_event_signal_t::slot_type& cb)
+	{
+		return mNewEventSignal.connect(cb);
+	};
 	
 protected:
 	en_map	mEventNotifications;
@@ -65,12 +91,12 @@ class LLEventNotifier
 class LLEventNotification
 {
 public:
-	LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName);
+	LLEventNotification(U32 eventId, F64 eventEpoch, std::string eventDateStr, std::string eventName);
 
 
 	U32					getEventID() const				{ return mEventID; }
 	const std::string	&getEventName() const			{ return mEventName; }
-	bool                isValid() const                 { return mEventID > 0 && mEventDateEpoch != 0 && mEventName.size() > 0; }
+	bool                isValid() const                 { return mEventID > 0 && mEventDateEpoch != 0 && !mEventName.empty(); }
 	const F64		    &getEventDateEpoch() const		{ return mEventDateEpoch; }
 	const std::string   &getEventDateStr() const        { return mEventDateStr; }
 	
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index 471becd0f7fe330dc0c34bc001a394f72cd2668d..21d9872395169f484edfc452562e8f81a6637521 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -165,8 +165,10 @@ class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
 	S32 mMapClicksNew;
 	S32 mProfileClicksNew;
 
+public:
     static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
 
+private:
 
 	typedef std::list<LLPanelClassifiedInfo*> panel_list_t;
 	static panel_list_t sAllPanels;
diff --git a/indra/newview/llsearchcombobox.h b/indra/newview/llsearchcombobox.h
index 68f397953291b68025b77280c9de915d0091332d..288f07554f1965f5c0e4437ca4ec00cf48b54adf 100644
--- a/indra/newview/llsearchcombobox.h
+++ b/indra/newview/llsearchcombobox.h
@@ -61,6 +61,11 @@ class LLSearchComboBox : public LLComboBox
 
 	~LLSearchComboBox();
 
+	/**
+	 * Sets focus to text box
+	 */
+	void focusTextEntry();
+
 protected:
 
 	LLSearchComboBox(const Params&p);
@@ -93,11 +98,6 @@ 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 a3073d8f44caf0a04df310d1db6afef39721762e..256610de4db96f06201f803d33a114cafaad24f6 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -216,6 +216,7 @@
 #if LL_WINDOWS
 #include "lldxhardware.h"
 #endif
+#include "fsfloatersearch.h"
 
 //
 // exported globals
@@ -2661,6 +2662,13 @@ void register_viewer_callbacks(LLMessageSystem* msg)
 	msg->setHandlerFuncFast(_PREHASH_PlacesReply, process_places_reply);
 	msg->setHandlerFuncFast(_PREHASH_GroupNoticesListReply, LLPanelGroupNotices::processGroupNoticesListReply);
 
+	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->setHandlerFuncFast(_PREHASH_AvatarPickerReply, LLFloaterAvatarPicker::processAvatarPickerReply);
 
 	msg->setHandlerFuncFast(_PREHASH_MapBlockReply, LLWorldMapMessage::processMapBlockReply);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 04f78d0b4ab03c3bb96a34f985aa54cb55eb1824..f9691acb60322e2db05747b7af4227d98a9e00a0 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -179,6 +179,7 @@
 #include "llpreviewtexture.h"
 #include "llscriptfloater.h"
 #include "llsyswellwindow.h"
+#include "fsfloatersearch.h"
 
 // *NOTE: Please add files in alphabetical order to keep merges easy.
 // [RLVa:KB] - Checked: 2010-03-11
@@ -390,7 +391,8 @@ 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("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
-    LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
+	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>);
 // [/SL:KB]
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
index 1655176523af31becb9b1cb2f67637b1670549e1..7f084147fefb2bc46750612f6d43926d06cdcb59 100644
--- a/indra/newview/llviewerinput.cpp
+++ b/indra/newview/llviewerinput.cpp
@@ -48,6 +48,8 @@
 #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"
 #include "rlvhandler.h"
@@ -674,6 +676,12 @@ 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)))
+    {
+        return true;
+    }
+
 	LLUICtrl* focus_ctrlp = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
 	if (KEYSTATE_UP == s &&
 		! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
diff --git a/indra/newview/skins/default/textures/icon_auction.tga b/indra/newview/skins/default/textures/icon_auction.tga
new file mode 100644
index 0000000000000000000000000000000000000000..baf7d0d000cdc3e1be7c1a9d0b1cc00f94eb4215
Binary files /dev/null and b/indra/newview/skins/default/textures/icon_auction.tga differ
diff --git a/indra/newview/skins/default/textures/icon_group.png b/indra/newview/skins/default/textures/icon_group.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c206fd883470dabb2235e6e44fb26dd4cd87fce
Binary files /dev/null and b/indra/newview/skins/default/textures/icon_group.png differ
diff --git a/indra/newview/skins/default/textures/icon_legacy_event.tga b/indra/newview/skins/default/textures/icon_legacy_event.tga
new file mode 100644
index 0000000000000000000000000000000000000000..7805dbce60eb7c58bb99826157ed222813c27419
Binary files /dev/null and b/indra/newview/skins/default/textures/icon_legacy_event.tga 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
new file mode 100644
index 0000000000000000000000000000000000000000..c344fb1e78887afe2b20ac4830ffb057772416cd
Binary files /dev/null and b/indra/newview/skins/default/textures/icon_legacy_event_adult.tga 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
new file mode 100644
index 0000000000000000000000000000000000000000..61c879bc923c7d1ee625a3995012a3ddecca363d
Binary files /dev/null and b/indra/newview/skins/default/textures/icon_legacy_event_mature.tga differ
diff --git a/indra/newview/skins/default/textures/icon_place.tga b/indra/newview/skins/default/textures/icon_place.tga
new file mode 100644
index 0000000000000000000000000000000000000000..e10655c6ecc5c78a990bb57dafedd954c5d9abc6
Binary files /dev/null and b/indra/newview/skins/default/textures/icon_place.tga differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_1.png b/indra/newview/skins/default/textures/icons/ProgressLarge_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ff277fc431d6d5f8b13baeb47b478f321e00ab79
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_1.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_10.png b/indra/newview/skins/default/textures/icons/ProgressLarge_10.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c94e21d89261478fdde301cf1309dcc3bbe3065
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_10.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_11.png b/indra/newview/skins/default/textures/icons/ProgressLarge_11.png
new file mode 100644
index 0000000000000000000000000000000000000000..89bea9b474bbbdb36be8e1024c00d226a22070f9
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_11.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_12.png b/indra/newview/skins/default/textures/icons/ProgressLarge_12.png
new file mode 100644
index 0000000000000000000000000000000000000000..da38475ba4dc61dfe4bff14a3175837f07d13fa3
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_12.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_2.png b/indra/newview/skins/default/textures/icons/ProgressLarge_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..c024275ebef799760ab3ae4f1ef9377df066632e
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_2.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_3.png b/indra/newview/skins/default/textures/icons/ProgressLarge_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..87b931e72e753c263fc0f07bddd2448ce123d8be
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_3.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_4.png b/indra/newview/skins/default/textures/icons/ProgressLarge_4.png
new file mode 100644
index 0000000000000000000000000000000000000000..6dbef74361edb829542a2809fb2a976f03008cac
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_4.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_5.png b/indra/newview/skins/default/textures/icons/ProgressLarge_5.png
new file mode 100644
index 0000000000000000000000000000000000000000..daccf9b375ffc677a02aa434bd0fc2514c1d614b
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_5.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_6.png b/indra/newview/skins/default/textures/icons/ProgressLarge_6.png
new file mode 100644
index 0000000000000000000000000000000000000000..cafddcb88dc21d60592ca403c46fd7fc0289adb9
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_6.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_7.png b/indra/newview/skins/default/textures/icons/ProgressLarge_7.png
new file mode 100644
index 0000000000000000000000000000000000000000..8acf6472d4d70d6fb758fa7321584c8bf7c6e621
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_7.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_8.png b/indra/newview/skins/default/textures/icons/ProgressLarge_8.png
new file mode 100644
index 0000000000000000000000000000000000000000..df0e825cef1f053d42c4fffca7efdd0e9f4969cf
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_8.png differ
diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_9.png b/indra/newview/skins/default/textures/icons/ProgressLarge_9.png
new file mode 100644
index 0000000000000000000000000000000000000000..293a7b8f5c6c7983e2e46c56cb661a1994ad3249
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ProgressLarge_9.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 40e8aebc4f175d6c5e00ec42aef47a495b6a93d9..4922b815a38498052fddafc0c7d65865b5aa62a1 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -876,4 +876,23 @@ with the same filename but different name
   <texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/>
   <texture name="Icon_Attachment_Small" file_name="icons/Icon_Attachment_Small.png"	preload="true"/>
   <texture name="Icon_Attachment_Large" file_name="icons/Icon_Attachment_Large.png"	preload="true"/>
+<texture name="Icon_Place" file_name="icon_place.tga" preload="false" />
+<texture name="Icon_Auction" file_name="icon_auction.tga" preload="false" />
+<texture name="Icon_Group" file_name="icon_group.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_fs_search.xml b/indra/newview/skins/default/xui/en/floater_fs_search.xml
new file mode 100644
index 0000000000000000000000000000000000000000..71f0b7a4444cb34877d115934d5ee4d84370ad5d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_fs_search.xml
@@ -0,0 +1,337 @@
+<?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="43"
+		name="snapshot"
+		top_pad="4"
+		width="280"/>
+		<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/panel_fs_search_legacy_classifieds.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml
new file mode 100644
index 0000000000000000000000000000000000000000..66c35558b10d93e30f6027ecaa2ac34ce6264715
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml
@@ -0,0 +1,169 @@
+<?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
new file mode 100644
index 0000000000000000000000000000000000000000..3f7e3290a78b879bf0ad4ea5634c092f5d108beb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml
@@ -0,0 +1,257 @@
+<?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 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
new file mode 100644
index 0000000000000000000000000000000000000000..90001952f7c38528926e77ddb32302e2e0b23bbc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml
@@ -0,0 +1,159 @@
+<?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
new file mode 100644
index 0000000000000000000000000000000000000000..bb03a1e9995b765a5386002da4a82bba89cb7c77
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml
@@ -0,0 +1,281 @@
+<?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
new file mode 100644
index 0000000000000000000000000000000000000000..28df02a7e3ced559795525a87414e0945231b539
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml
@@ -0,0 +1,89 @@
+<?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
new file mode 100644
index 0000000000000000000000000000000000000000..09c142b8fc18688df44226384e6e7ae8a28a72ca
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml
@@ -0,0 +1,169 @@
+<?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
new file mode 100644
index 0000000000000000000000000000000000000000..382a5e8945eafd325fbbb81c5225acdb8c52edc9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml
@@ -0,0 +1,21 @@
+<?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/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index fda6fc2da86a5f5b3e11001372b95cd789c16320..a756ef8ca865d05bd97ff40256dfa855b817a22d 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2914,13 +2914,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&amp;Culture">Arts &amp; Culture</string>
+	<string name="Arts and 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&amp;Nature">Parks &amp; Nature</string>
+	<string name="Parks and Nature">Parks &amp; Nature</string>
 	<string name="Residential">Residential</string>
 	<!--<string name="Shopping">Shopping</string>	-->
 	<string name="Stage">Stage</string>
@@ -4366,6 +4366,13 @@ 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="AvatarTyping">Typing</string>
   <string name="UnknownAvatar">Unknown Avatar</string>