diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 00d92b5ac20725289cdd0510152f05d81ae8329b..637db2c5c261c800c153d0c56ec3be1ffb61d79b 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -44,6 +44,7 @@ set(llcommon_SOURCE_FILES
     llcoros.cpp
     llcrc.cpp
     llcriticaldamp.cpp
+    llcurrencywrapper.cpp
     lldate.cpp
     lldeadmantimer.cpp
     lldependencies.cpp
@@ -146,6 +147,7 @@ set(llcommon_HEADER_FILES
     llcoros.h
     llcrc.h
     llcriticaldamp.h
+    llcurrencywrapper.h
     lldate.h
     lldeadmantimer.h
     lldefs.h
diff --git a/indra/llcommon/llcurrencywrapper.cpp b/indra/llcommon/llcurrencywrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..65dbabe875c0cabb223071789590785a2045a4d1
--- /dev/null
+++ b/indra/llcommon/llcurrencywrapper.cpp
@@ -0,0 +1,70 @@
+/** 
+ * @file llcurrencywrapper.cpp
+ * @brief Currency wrapping class from the tea viewer helper library
+ *
+ * Copyright (C) 2012 arminweatherwax (at) lavabit.com
+ * Copyright (C) 2015 Cinder Roxley <cinder@sdf.org>
+ * You can use it under the following license:
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ * 
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "llcurrencywrapper.h"
+#include <boost/algorithm/string.hpp>
+
+
+void LLCurrencyWrapper::setCurrency(const std::string& currency)
+{
+    mCurrency = currency;
+    mChangedSignal();
+}
+
+
+void LLCurrencyWrapper::setHomeCurrency(const std::string& currency)
+{
+    mHomeCurrency = currency;
+    setCurrency(currency);
+}
+
+std::string LLCurrencyWrapper::wrapCurrency(const std::string& to_substitute) const
+{
+	return boost::algorithm::replace_all_copy(to_substitute, "L$", mCurrency);
+}
+
+void LLCurrencyWrapper::wrapCurrency(std::string& to_substitute) const
+{
+	boost::algorithm::replace_all(to_substitute, "L$", mCurrency);
+}
+
+boost::signals2::connection LLCurrencyWrapper::addCurrencyChangedCb(currency_changed_callback_t cb)
+{
+    return mChangedSignal.connect(cb);
+}
+
+void LLCurrencyWrapper::removeCurrencyChangedCb(boost::signals2::connection cb)
+{
+    mChangedSignal.disconnect(cb);
+}
+
diff --git a/indra/llcommon/llcurrencywrapper.h b/indra/llcommon/llcurrencywrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..b2b38a5af1fb9db141b000d460928c0051e8cd1a
--- /dev/null
+++ b/indra/llcommon/llcurrencywrapper.h
@@ -0,0 +1,65 @@
+/** 
+ * @file llcurrencywrapper.h
+ * @brief Currency wrapping class from the tea viewer helper library
+ *
+ * Copyright (C) 2012 arminweatherwax (at) lavabit.com
+ * Copyright (C) 2015 Cinder Roxley <cinder@sdf.org>
+ * You can use it under the following license:
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ * 
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef LL_CURRENCYWRAPPER_H
+#define LL_CURRENCYWRAPPER_H
+
+#include "llsingleton.h"
+#include <string>
+#include <boost/signals2.hpp>
+
+class LLCurrencyWrapper final : public LLSingleton<LLCurrencyWrapper>
+{
+	LLSINGLETON_EMPTY_CTOR(LLCurrencyWrapper);
+
+public:
+    void setCurrency(const std::string& currency);
+    void setHomeCurrency(const std::string& currency);
+    const std::string& getCurrency() const { return mCurrency; }
+    const std::string& getHomeCurrency() const { return mHomeCurrency; }
+    std::string wrapCurrency(const std::string& to_substitute) const;
+    void wrapCurrency(std::string& to_substitute) const;
+
+    using currency_changed_signal_t = boost::signals2::signal<void()>;
+    using currency_changed_callback_t = std::function<void()>;
+
+    boost::signals2::connection addCurrencyChangedCb(currency_changed_callback_t cb);
+    void removeCurrencyChangedCb(boost::signals2::connection cb);
+
+private:	
+	std::string mCurrency;
+    std::string mHomeCurrency;
+    currency_changed_signal_t mChangedSignal;
+};
+
+#endif //LL_CURRENCYWRAPPER_H
diff --git a/indra/llinventory/lltransactionflags.cpp b/indra/llinventory/lltransactionflags.cpp
index e21f29df41f33abb4ccea9230f4454bac52c5509..b3535db47a35613d1a3ca591033b28e9a1163063 100644
--- a/indra/llinventory/lltransactionflags.cpp
+++ b/indra/llinventory/lltransactionflags.cpp
@@ -30,6 +30,7 @@
 #include "lluuid.h"
 #include "lltransactionflags.h"
 #include "lltransactiontypes.h"
+#include "llcurrencywrapper.h"
  
 const U8 TRANSACTION_FLAGS_NONE = 0;
 const U8 TRANSACTION_FLAG_SOURCE_GROUP = 1;
@@ -111,7 +112,7 @@ std::string build_transfer_message_to_source(
 		// *NOTE: Do not change these strings!  The viewer matches
 		// them in llviewermessage.cpp to perform localization.
 		// If you need to make changes, add a new, localizable message. JC
-		ostr << "You paid L$" << amount;
+		ostr << LLCurrencyWrapper::instance().wrapCurrency("You paid L$") << amount;
 		switch(transaction_type)
 		{
 		case TRANS_GROUP_CREATE:
@@ -129,7 +130,7 @@ std::string build_transfer_message_to_source(
 	}
 	else
 	{
-		ostr << "You paid " << dest_name << " L$" << amount;
+		ostr << "You paid " << dest_name << LLCurrencyWrapper::instance().wrapCurrency(" L$") << amount;
 		append_reason(ostr, transaction_type, description);
 	}
 	ostr << ".";
@@ -160,7 +161,7 @@ std::string build_transfer_message_to_destination(
 	// *NOTE: Do not change these strings!  The viewer matches
 	// them in llviewermessage.cpp to perform localization.
 	// If you need to make changes, add a new, localizable message. JC
-	ostr << source_name << " paid you L$" << amount;
+	ostr << source_name << LLCurrencyWrapper::instance().wrapCurrency(" paid you L$") << amount;
 	append_reason(ostr, transaction_type, description);
 	ostr << ".";
 	return ostr.str();
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 05b31e1eaf805c9c74680781cc48767c0d3ce3a2..d56e96825b7c830d3363a55aacd3d2799c265d13 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -620,6 +620,13 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
+void LLButton::updateCurrencySymbols()
+{
+    mUnselectedLabel.dirty();
+    mSelectedLabel.dirty();
+    mDisabledSelectedLabel.dirty();
+}
+
 void LLButton::getOverlayImageSize(S32& overlay_width, S32& overlay_height)
 {
 	overlay_width = mImageOverlay->getWidth();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 8bc68a9ba87e0417b810232ebbfefab15a0f2055..c69b5368a5a43db7010cf5172a8ef395dc090cb5 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -284,6 +284,8 @@ class LLButton
 	
 	void 		setAutoResize(bool auto_resize) { mAutoResize = auto_resize; }
 
+    void        updateCurrencySymbols();
+
 protected:
 	LLPointer<LLUIImage> getImageUnselected() const	{ return mImageUnselected; }
 	LLPointer<LLUIImage> getImageSelected() const	{ return mImageSelected; }
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 6c8010518d97af2774ca3a3c2a7bbba086da1bed..d5fb2287c6b13afdeea9a95540f91e920e051fae 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2019,6 +2019,13 @@ void LLFloater::updateTransparency(ETypeTransparency transparency_type)
 	updateTransparency(this, transparency_type);
 }
 
+void LLFloater::updateCurrencySymbol()
+{
+    mTitle.dirty();
+    mShortTitle.dirty();
+    applyTitle();
+}
+
 void	LLFloater::setCanMinimize(BOOL can_minimize)
 {
 	// if removing minimize/restore button programmatically,
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index df8359112e5dac2113fff0d7ec8bc9d62aa67557..39b6d427e0973a745bb2defa4b364de15e4ea756 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -365,6 +365,8 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 
 	void			updateTransparency(ETypeTransparency transparency_type);
 		
+    void            updateCurrencySymbol();
+
 	void			enableResizeCtrls(bool enable, bool width = true, bool height = true);
 
 	bool			isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mPositioning); }
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index cfe3f53b7d99ec7c13bf81724ca33a181482806f..4fede1ed02502d43d68478e31a36a868547a2a18 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -161,6 +161,12 @@ BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text
 	return TRUE;
 }
 
+void LLTextBox::updateCurrencySymbols()
+{
+    mLabel.dirty();
+    mText.dirty();
+    LLTextBase::setText(mText.getString());
+}
 
 void LLTextBox::reshapeToFitText(BOOL called_from_parent)
 {
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 7a9f47eddca8a24bdd58b697cf4ca5f6018e76d5..0f16b3530cb09de30092b18b73c8ad9548e0ffaf 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -68,6 +68,8 @@ class LLTextBox :
 	/*virtual*/ LLSD	getValue() const;
 	/*virtual*/ BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
 
+    void updateCurrencySymbols();
+
 	void			setShowCursorHand(bool show_cursor) { mShowCursorHand = show_cursor; }
 
 protected:
diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp
index d71fe7721c90bb6c0f10e30eb315e36052179315..b1fe578b7b1f3331eba34ab54cf9e879e3ef518c 100644
--- a/indra/llui/lluistring.cpp
+++ b/indra/llui/lluistring.cpp
@@ -27,6 +27,7 @@
 #include "linden_common.h"
 #include "lluistring.h"
 
+#include "llcurrencywrapper.h"
 #include "llfasttimer.h"
 #include "llsd.h"
 #include "lltrans.h"
@@ -148,6 +149,9 @@ void LLUIString::updateResult() const
 		combined_args.insert(mArgs->begin(), mArgs->end());
 	}
 	LLStringUtil::format(mResult, combined_args);
+	// Impact on lag: at average frame time 15.9 ms
+	// FTM_UI_STRING 0.01ms both with/without wrapCurrency so bite me.
+	LLCurrencyWrapper::instance().wrapCurrency(mResult);
 }
 
 void LLUIString::updateWResult() const
diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h
index 7bd566f6b83bde1a386f453bcebd5a1aa641d559..beaad19989d8ca515560761554549b20a38c7fef 100644
--- a/indra/llui/lluistring.h
+++ b/indra/llui/lluistring.h
@@ -94,10 +94,10 @@ class LLUIString
 	void insert(S32 charidx, const LLWString& wchars);
 	void replace(S32 charidx, llwchar wc);
 
-private:
 	// something changed, requiring reformatting of strings
 	void dirty();
 
+private:
 	std::string& getUpdatedResult() const { if (mNeedsResult) { updateResult(); } return mResult; }
 	LLWString& getUpdatedWResult() const{ if (mNeedsWResult) { updateWResult(); } return mWResult; }
 
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 232e461fd0fa076dbfea12378248455e842e80d6..6385f72665a4d6cc14496c0024d0580dc509f5c6 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -44,6 +44,7 @@
 #include "llviewchildren.h"
 #include "llxmlrpctransaction.h"
 #include "llviewernetwork.h"
+#include "llviewerregion.h"
 #include "llpanel.h"
 
 
@@ -279,17 +280,15 @@ void LLCurrencyUIManager::Impl::finishCurrencyBuy()
 void LLCurrencyUIManager::Impl::startTransaction(TransactionType type,
 		const char* method, LLXMLRPCValue params)
 {
-	static std::string transactionURI;
-	if (transactionURI.empty())
-	{
-		transactionURI = LLGridManager::getInstance()->getHelperURI() + "currency.php";
-	}
+    LLViewerRegion* region = gAgent.getRegion();
+    const std::string transaction_uri = (region != nullptr) ? region->getBuyCurrencyServerURL()
+        : LLGridManager::getInstance()->getHelperURI() + "currency.php";
 
 	delete mTransaction;
 
 	mTransactionType = type;
 	mTransaction = new LLXMLRPCTransaction(
-		transactionURI,
+        transaction_uri,
 		method,
 		params,
 		false /* don't use gzip */
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index 3e26df497aa3436a9d3c318408c61d6286b48899..bda4e3748199890d5eb5035973ea48082aa5e5b1 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -39,6 +39,7 @@
 #include "llagent.h"
 #include "llassetstorage.h"
 #include "llcombobox.h"
+#include "llcurrencywrapper.h"
 #include "llestateinfomodel.h"
 #include "llmimetypes.h"
 #include "llnotifications.h"
@@ -506,7 +507,7 @@ void LLFloaterAuction::doSellToAnyone()
 		body["sale_price"] = parcelp->getArea();	// Sell for L$1 per square meter
 		body["auth_buyer_id"] = LLUUID::null;		// To anyone
 
-		LL_INFOS() << "Sending parcel update to sell to anyone for L$1 via capability to: "
+		LL_INFOS() << LLCurrencyWrapper::instance().wrapCurrency("Sending parcel update to sell to anyone for L$1 via capability to: ")
 			<< mParcelUpdateCapUrl << LL_ENDL;
 
         LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index 5876969c40c0698419aea58ac52be3319af805d7..e3e9b8044c9b29adf00a904ffab50f6f8f7bbd45 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -28,6 +28,8 @@
 
 #include "llfloaterbuycurrency.h"
 
+#include "llcurrencywrapper.h"
+
 // viewer includes
 #include "llcurrencyuimanager.h"
 #include "llfloater.h"
@@ -38,6 +40,7 @@
 #include "llstatusbar.h"
 #include "lltextbox.h"
 #include "llviewchildren.h"
+#include "llviewernetwork.h"
 #include "llviewerwindow.h"
 #include "lluictrlfactory.h"
 #include "llweb.h"
@@ -53,8 +56,6 @@ class LLFloaterBuyCurrencyUI final
 	LLFloaterBuyCurrencyUI(const LLSD& key);
 	virtual ~LLFloaterBuyCurrencyUI();
 
-
-public:
 	LLViewChildren		mChildren;
 	LLCurrencyUIManager	mManager;
 	
@@ -62,13 +63,13 @@ class LLFloaterBuyCurrencyUI final
 	S32			mTargetPrice;
 	S32			mRequiredAmount;
 	
-public:
 	void noTarget();
 	void target(const std::string& name, S32 price);
 	
 	virtual BOOL postBuild();
 	
 	void updateUI();
+    void updateCurrencySymbols();
 	void collapsePanels(bool collapse);
 
 	virtual void draw();
@@ -76,6 +77,8 @@ class LLFloaterBuyCurrencyUI final
 
 	void onClickBuy();
 	void onClickCancel();
+
+    boost::signals2::connection mCurrencyChangedSlot;
 };
 
 LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key)
@@ -95,6 +98,8 @@ LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI(const LLSD& key)
 
 LLFloaterBuyCurrencyUI::~LLFloaterBuyCurrencyUI()
 {
+    if (mCurrencyChangedSlot.connected())
+        mCurrencyChangedSlot.disconnect();
 }
 
 
@@ -134,10 +139,17 @@ BOOL LLFloaterBuyCurrencyUI::postBuild()
 	
 	getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickBuy, this));
 	getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickCancel, this));
+	if (LLGridManager::instance().isInOpenSim())
+	{
+		getChild<LLTextBox>("currency_links")->setText(LLStringExplicit(""));
+	}
 	
 	center();
 	
 	updateUI();
+
+    mCurrencyChangedSlot = LLCurrencyWrapper::instance().addCurrencyChangedCb(
+        std::bind(&LLFloaterBuyCurrencyUI::updateCurrencySymbols, this));
 	
 	return TRUE;
 }
@@ -185,7 +197,15 @@ void LLFloaterBuyCurrencyUI::updateUI()
 		LLSD args;
 		args["TITLE"] = getString("info_cannot_buy");
 		args["MESSAGE"] = mManager.errorMessage();
-		LLNotificationsUtil::add("CouldNotBuyCurrency", args);
+		if( !LLGridManager::getInstance()->isInSecondlife() )
+		{
+			args["LINK"] = mManager.errorURI();
+			LLNotificationsUtil::add("CouldNotBuyCurrencyOS", args);
+		}
+		else
+		{
+			LLNotificationsUtil::add("CouldNotBuyCurrency", args);
+		}
 		mManager.clearError();
 		closeFloater();
 	}
@@ -240,6 +260,16 @@ void LLFloaterBuyCurrencyUI::updateUI()
 	getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError && !getChildView("currency_est")->getVisible());
 }
 
+void LLFloaterBuyCurrencyUI::updateCurrencySymbols()
+{
+    updateCurrencySymbol();
+    getChild<LLTextBox>("info_need_more")->updateCurrencySymbols();
+    getChild<LLTextBox>("info_buying")->updateCurrencySymbols();
+    getChild<LLTextBox>("currency_label")->updateCurrencySymbols();
+    getChild<LLTextBox>("purchase_warning_repurchase")->updateCurrencySymbols();
+    getChild<LLTextBox>("purchase_warning_notenough")->updateCurrencySymbols();
+}
+
 void LLFloaterBuyCurrencyUI::collapsePanels(bool collapse)
 {
 	LLLayoutPanel* price_panel = getChild<LLLayoutPanel>("layout_panel_price");
@@ -289,15 +319,33 @@ LLFetchAvatarPaymentInfo* LLFloaterBuyCurrency::sPropertiesRequest = NULL;
 // static
 void LLFloaterBuyCurrency::buyCurrency()
 {
-	delete sPropertiesRequest;
-	sPropertiesRequest = new LLFetchAvatarPaymentInfo(false);
+	if (LLGridManager::instance().isInOpenSim())
+	{
+		LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
+		ui->noTarget();
+		ui->updateUI();
+	}
+	else
+	{
+		delete sPropertiesRequest;
+		sPropertiesRequest = new LLFetchAvatarPaymentInfo(false);
+	}
 }
 
 // static
 void LLFloaterBuyCurrency::buyCurrency(const std::string& name, S32 price)
 {
-	delete sPropertiesRequest;
-	sPropertiesRequest = new LLFetchAvatarPaymentInfo(true, name, price);
+	if (LLGridManager::instance().isInOpenSim())
+	{
+		LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
+		ui->target(name, price);
+		ui->updateUI();
+	}
+	else
+	{
+		delete sPropertiesRequest;
+		sPropertiesRequest = new LLFetchAvatarPaymentInfo(true, name, price);
+	}
 }
 
 // static
diff --git a/indra/newview/llpanelgroupcreate.cpp b/indra/newview/llpanelgroupcreate.cpp
index 52be75072cad4104c7ef714451bc890c85312c99..06c9424160c2b64c0ad1a723318c049a00ceb1a4 100644
--- a/indra/newview/llpanelgroupcreate.cpp
+++ b/indra/newview/llpanelgroupcreate.cpp
@@ -27,6 +27,8 @@
 
 #include "llpanelgroupcreate.h"
 
+#include "llcurrencywrapper.h"
+
 // UI includes
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
@@ -149,7 +151,7 @@ void LLPanelGroupCreate::addMembershipRow(const std::string &name)
         }
         item_params.columns.add(cell_params);
         cell_params.column = "clmn_price";
-        cell_params.value = llformat("L$ %d",LLAgentBenefitsMgr::get(name).getCreateGroupCost());
+        cell_params.value = LLCurrencyWrapper::instance().wrapCurrency(llformat("L$ %d",LLAgentBenefitsMgr::get(name).getCreateGroupCost()));
         item_params.columns.add(cell_params);
         mMembershipList->addRow(item_params);
     }
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 9279fec6cccf1636934942556cf6956a3384674e..5aa7447ff11d6c54c61a3afd1b74f538c6f7643e 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -30,6 +30,7 @@
 
 #include "lluiconstants.h"
 #include "roles_constants.h"
+#include "llcurrencywrapper.h"
 
 #include "llparcel.h"
 #include "llqueryflags.h"
@@ -844,7 +845,7 @@ void LLPanelGroupLandMoney::processPlacesReply(LLMessageSystem* msg, void**)
 	group_id_map_t::iterator found_it = sGroupIDs.find(group_id);
 	if(found_it == sGroupIDs.end())
 	{
-		LL_INFOS() << "Group Panel Land L$ " << group_id << " no longer in existence."
+		LL_INFOS() << LLCurrencyWrapper::instance().wrapCurrency("Group Panel Land L$ ") << group_id << " no longer in existence."
 				<< LL_ENDL;
 		return;
 	}
@@ -1136,7 +1137,7 @@ void LLPanelGroupLandMoney::processGroupAccountDetailsReply(LLMessageSystem* msg
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		LL_WARNS() << "Got group L$ history reply for another agent!" << LL_ENDL;
+		LL_WARNS() << LLCurrencyWrapper::instance().wrapCurrency("Got group L$ history reply for another agent!") << LL_ENDL;
 		return;
 	}
 
@@ -1313,7 +1314,7 @@ void LLPanelGroupLandMoney::processGroupAccountTransactionsReply(LLMessageSystem
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		LL_WARNS() << "Got group L$ history reply for another agent!" << LL_ENDL;
+		LL_WARNS() << LLCurrencyWrapper::instance().wrapCurrency("Got group L$ history reply for another agent!") << LL_ENDL;
 		return;
 	}
 
@@ -1493,7 +1494,7 @@ void LLPanelGroupLandMoney::processGroupAccountSummaryReply(LLMessageSystem* msg
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		LL_WARNS() << "Got group L$ history reply for another agent!" << LL_ENDL;
+		LL_WARNS() << LLCurrencyWrapper::instance().wrapCurrency("Got group L$ history reply for another agent!") << LL_ENDL;
 		return;
 	}
 
@@ -1505,7 +1506,7 @@ void LLPanelGroupLandMoney::processGroupAccountSummaryReply(LLMessageSystem* msg
 	self = get_ptr_in_map(LLGroupMoneyTabEventHandler::sInstanceIDs, request_id);
 	if (!self)
 	{
-		LL_WARNS() << "GroupAccountSummary recieved for non-existent group L$ planning tab." << LL_ENDL;
+		LL_WARNS() << LLCurrencyWrapper::instance().wrapCurrency("GroupAccountSummary recieved for non-existent group L$ planning tab.") << LL_ENDL;
 		return;
 	}
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index b484d9acf5556cb3d2030fab907204be136a664c..7923ad2ebc720267e88b236a22264a17d9c581db 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -53,6 +53,7 @@
 #include "llexperiencecache.h"
 #include "lllandmark.h"
 #include "llcachename.h"
+#include "llcurrencywrapper.h"
 #include "lldir.h"
 #include "lldonotdisturbnotificationstorage.h"
 #include "llerrorcontrol.h"
@@ -3682,11 +3683,11 @@ bool process_login_success_response(U32& first_sim_size_x, U32& first_sim_size_y
 	}
 
 	// Set the location of the snapshot sharing config endpoint
-	std::string snapshot_config_url = response["snapshot_config_url"];
-	if(!snapshot_config_url.empty())
-	{
-		gSavedSettings.setString("SnapshotConfigURL", snapshot_config_url);
-	}
+	//std::string snapshot_config_url = response["snapshot_config_url"];
+	//if(!snapshot_config_url.empty())
+	//{
+	//	gSavedSettings.setString("SnapshotConfigURL", snapshot_config_url);
+	//}
 
 	// Start the process of fetching the OpenID session cookie for this user login
 	std::string openid_url = response["openid_url"];
@@ -3716,6 +3717,16 @@ bool process_login_success_response(U32& first_sim_size_x, U32& first_sim_size_y
 		}
 	}
 
+	std::string currency = "L$";
+	if(response.has("currency"))
+	{
+		currency = response["currency"].asString();
+	}
+	else if (LLGridManager::getInstance()->isInOpenSim())
+	{
+		currency = "$";
+	}
+	LLCurrencyWrapper::getInstance()->setHomeCurrency(currency);
 
 	bool success = false;
 	// JC: gesture loading done below, when we have an asset system
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 66b922757cc8da175bd85ca33f38479c8524c5a5..844acf6bac5d47a70214776ef1d6ba84f25bbc0a 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -137,6 +137,11 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
 
 LLStatusBar::~LLStatusBar()
 {
+    if (mCurrencyChangedSlot.connected())
+	{
+        mCurrencyChangedSlot.disconnect();
+	}
+
 	delete mBalanceTimer;
 	mBalanceTimer = NULL;
 
@@ -171,8 +176,8 @@ BOOL LLStatusBar::postBuild()
 
 	mTextTime = getChild<LLTextBox>("TimeText" );
 	
-	getChild<LLUICtrl>("buyL")->setCommitCallback(
-		boost::bind(&LLStatusBar::onClickBuyCurrency, this));
+	mBtnBuyL = getChild<LLButton>("buyL");
+	mBtnBuyL->setCommitCallback(boost::bind(&LLStatusBar::onClickBuyCurrency, this));
 
     getChild<LLUICtrl>("goShop")->setCommitCallback(boost::bind(&LLWeb::loadURL, gSavedSettings.getString("MarketplaceURL"), LLStringUtil::null, LLStringUtil::null));
 
@@ -297,6 +302,8 @@ BOOL LLStatusBar::postBuild()
 		updateMenuSearchPosition();
 	}
 
+    mCurrencyChangedSlot = LLCurrencyWrapper::getInstance()->addCurrencyChangedCb(
+        [&] { mBtnBuyL->updateCurrencySymbols(); sendMoneyBalanceRequest(); });
 	return TRUE;
 }
 
@@ -542,7 +549,7 @@ S32 LLStatusBar::getSquareMetersLeft() const
 	return mSquareMetersCredit - mSquareMetersCommitted;
 }
 
-void LLStatusBar::onClickBuyCurrency()
+void LLStatusBar::onClickBuyCurrency() const
 {
 	// open a currency floater - actual one open depends on 
 	// value specified in settings.xml
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index ab6e9007d54ff317640cd8f2873ddb42d37691b2..82832f86c94da04b50c4fc0e2d5823d08baa5dd1 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -28,6 +28,7 @@
 #define LL_LLSTATUSBAR_H
 
 #include "llpanel.h"
+#include "llcurrencywrapper.h"
 
 // "Constants" loaded from settings.xml at start time
 extern S32 STATUS_BAR_HEIGHT;
@@ -99,7 +100,7 @@ class LLStatusBar final
 
 private:
 	
-	void onClickBuyCurrency();
+	void onClickBuyCurrency() const;
 	void onVolumeChanged(const LLSD& newvalue);
 
 	void onMouseEnterPresetsCamera();
@@ -140,6 +141,7 @@ class LLStatusBar final
 	LLButton	*mBtnAO;
 	LLButton	*mBtnVolume;
 	LLTextBox	*mBoxBalance;
+	LLButton	*mBtnBuyL;
 	LLButton	*mMediaToggle;
 	LLFrameTimer	mClockUpdateTimer;
 	LLFrameTimer*	mFPSUpdateTimer;
@@ -156,6 +158,8 @@ class LLStatusBar final
 	ALPanelQuickSettingsPulldown* mPanelQuickSettingsPulldown;
 	LLPanelVolumePulldown* mPanelVolumePulldown;
 	LLPanelNearByMedia*	mPanelNearByMedia;
+
+    boost::signals2::connection mCurrencyChangedSlot;
 };
 
 // *HACK: Status bar owns your cached money balance. JC
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 9d15ddce714d5cc14c3ac59ed175a5e9e289ecdb..b9909ee9f6f73110977f2ee1351c62dc4a0dfc30 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -32,6 +32,7 @@
 #include "llaudioengine.h" 
 #include "llavataractions.h"
 #include "llavatarnamecache.h"		// IDEVO HACK
+#include "llcurrencywrapper.h"
 #include "lleconomy.h"
 #include "lleventtimer.h"
 #include "llfloaterreg.h"
@@ -393,7 +394,7 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_
 	{
 		if (uuid.isNull())
 		{
-			LL_WARNS() << "Failed to send L$ gift to to Null UUID." << LL_ENDL;
+			LL_WARNS() << LLCurrencyWrapper::instance().wrapCurrency("Failed to send L$ gift to to Null UUID.") << LL_ENDL;
 			return;
 		}
 //		gStatusBar->debitBalance(amount);
@@ -4888,7 +4889,7 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )
 	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_SquareMetersCredit, credit);
 	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_SquareMetersCommitted, committed);
 	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_Description, desc);
-	LL_INFOS("Messaging") << "L$, credit, committed: " << balance << " " << credit << " "
+	LL_INFOS("Messaging") << LLCurrencyWrapper::instance().wrapCurrency("L$, credit, committed: ") << balance << " " << credit << " "
 			<< committed << LL_ENDL;
     
 	if (gStatusBar)
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 08f63bdc63191b4b5731aaa6300f929238fe1034..447d868443461ed456231f7b8ed7671bae6e10f4 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -88,6 +88,8 @@
 
 #include <boost/regex.hpp>
 
+#include "llcurrencywrapper.h"
+
 
 // When we receive a base grant of capabilities that has a different number of 
 // capabilities than the original base grant received for the region, print 
@@ -2315,6 +2317,7 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
 	if (LLGridManager::getInstance()->isInOpenSim())
 	{
 		setGodnames();
+        std::string cur_symbol = LLCurrencyWrapper::instance().getHomeCurrency();
 		if (mSimulatorFeatures.has("OpenSimExtras"))
 		{
 			const LLSD& extras(mSimulatorFeatures["OpenSimExtras"]);
@@ -2326,6 +2329,11 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
 					LLGridManager::getInstance()->addRemoteGrid(grid_url, LLGridManager::ADD_HYPERGRID);
 			}
 
+			if (extras.has("currency"))
+			{
+				cur_symbol = extras["currency"].asString();
+			}
+
 			mMinSimHeight = extras.has("MinSimHeight") ? extras["MinSimHeight"].asReal() : OS_MIN_OBJECT_Z;
 			mMaxSimHeight = extras.has("MaxSimHeight") ? extras["MaxSimHeight"].asReal() : OS_MAX_OBJECT_Z;
 			mMinPrimScale = extras.has("MinPrimScale") ? extras["MinPrimScale"].asReal() : OS_MIN_PRIM_SCALE;
@@ -2344,6 +2352,11 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
 			mMinPhysPrimScale = OS_MIN_PRIM_SCALE;
 			mMaxPhysPrimScale = OS_DEFAULT_MAX_PRIM_SCALE;
 		}
+		
+        if (LLCurrencyWrapper::instance().getCurrency() != cur_symbol)
+        {
+            LLCurrencyWrapper::instance().setCurrency(cur_symbol);
+        }
 	}
 	else
 	{
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f64a92fb3a4d0aea80b60ad87622eb2b7fb4a6ea..7657da6a015fbe0513fa240b53e58e45b9df3826 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1341,6 +1341,25 @@ You must agree to the Terms and Conditions, Privacy Policy, and Terms of Service
      yestext="OK"/>
   </notification>
   
+  <notification
+   icon="alertmodal.tga"
+   name="CouldNotBuyCurrencyOS"
+   type="alertmodal">
+[TITLE]
+[MESSAGE]
+    <tag>confirm</tag>
+    <url
+	option="0"
+	name="url"
+	target = "_external">
+		[LINK]
+    </url>
+    <usetemplate
+     name="okcancelbuttons"
+     notext="No"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="CouldNotPutOnOutfit"