diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index fe422e92b7c8155382748918afea39e1c095dc2c..1efe2adbbe8a8d635ac1049f07a81d5d5da0e4e8 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -341,7 +341,8 @@ void LLURI::parseAuthorityAndPathUsingOpaque()
 {
 	if (mScheme == "http" || mScheme == "https" ||
 		mScheme == "ftp" || mScheme == "secondlife" || 
-		mScheme == "x-grid-location-info")
+		mScheme == "x-grid-info" ||
+		mScheme == "x-grid-location-info") // legacy
 	{
 		if (mEscapedOpaque.substr(0,2) != "//")
 		{
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index e04dd726db88ddd6bee27eceac9d97aa5268e532..12532c53dcf34694db736a3c105120d29a23e0e8 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -41,7 +41,8 @@
 #include "message.h"
 #include "llexperiencecache.h"
 
-#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
+#define APP_HEADER_REGEX "((((x-grid-info://)|(x-grid-location-info://))[-\\w\\.]+(:\\d+)?/app)|(secondlife:///app))"
+#define X_GRID_OR_SECONDLIFE_HEADER_REGEX "((((x-grid-info://)|(x-grid-location-info://))[-\\w\\.]+(:\\d+)?/)|(secondlife://))"
 
 // Utility functions
 std::string localize_slapp_label(const std::string& url, const std::string& full_name);
@@ -739,7 +740,7 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url)
 //
 // LLUrlEntryAgentName describes a Second Life agent name Url, e.g.,
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
 //
 void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,
 										const LLAvatarName& av_name)
@@ -804,7 +805,7 @@ LLStyle::Params LLUrlEntryAgentName::getStyle() const
 //
 // LLUrlEntryAgentCompleteName describes a Second Life agent complete name Url, e.g.,
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
 //
 LLUrlEntryAgentCompleteName::LLUrlEntryAgentCompleteName()
 {
@@ -820,7 +821,7 @@ std::string LLUrlEntryAgentCompleteName::getName(const LLAvatarName& avatar_name
 //
 // LLUrlEntryAgentLegacyName describes a Second Life agent legacy name Url, e.g.,
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/legacyname
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/legacyname
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/legacyname
 //
 LLUrlEntryAgentLegacyName::LLUrlEntryAgentLegacyName()
 {
@@ -836,7 +837,7 @@ std::string LLUrlEntryAgentLegacyName::getName(const LLAvatarName& avatar_name)
 //
 // LLUrlEntryAgentDisplayName describes a Second Life agent display name Url, e.g.,
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
 //
 LLUrlEntryAgentDisplayName::LLUrlEntryAgentDisplayName()
 {
@@ -852,7 +853,7 @@ std::string LLUrlEntryAgentDisplayName::getName(const LLAvatarName& avatar_name)
 //
 // LLUrlEntryAgentUserName describes a Second Life agent user name Url, e.g.,
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
 //
 LLUrlEntryAgentUserName::LLUrlEntryAgentUserName()
 {
@@ -890,7 +891,7 @@ std::string LLUrlEntryAgentRLVAnonymizedName::getName(const LLAvatarName& avatar
 // LLUrlEntryGroup Describes a Second Life group Url, e.g.,
 // secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
 // secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
-// x-grid-location-info://lincoln.lindenlab.com/app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
+// x-grid-info://lincoln.lindenlab.com/app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
 //
 LLUrlEntryGroup::LLUrlEntryGroup()
 {
@@ -971,7 +972,7 @@ LLUrlEntryInventory::LLUrlEntryInventory()
 	//*TODO: add supporting of inventory item names with whitespaces
 	//this pattern cann't parse for example 
 	//secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces&param2=value
-	//x-grid-location-info://lincoln.lindenlab.com/app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces&param2=value
+	//x-grid-info://lincoln.lindenlab.com/app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces&param2=value
 	mPattern = boost::regex(APP_HEADER_REGEX "/inventory/[\\da-f-]+/\\w+\\S*",
 							boost::regex::perl|boost::regex::icase);
 	mMenuName = "menu_url_inventory.xml";
@@ -989,7 +990,7 @@ std::string LLUrlEntryInventory::getLabel(const std::string &url, const LLUrlLab
 //
 LLUrlEntryObjectIM::LLUrlEntryObjectIM()
 {
-	mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\?\\S*\\w",
+	mPattern = boost::regex(APP_HEADER_REGEX "/objectim/[\\da-f-]+\?\\S*\\w",
 							boost::regex::perl|boost::regex::icase);
 	mMenuName = "menu_url_objectim.xml";
 }
@@ -1022,7 +1023,7 @@ std::set<LLUrlEntryParcel*> LLUrlEntryParcel::sParcelInfoObservers;
 ///
 /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
 /// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
-/// x-grid-location-info://lincoln.lindenlab.com/app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
+/// x-grid-info://lincoln.lindenlab.com/app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
 ///
 LLUrlEntryParcel::LLUrlEntryParcel()
 {
@@ -1117,7 +1118,7 @@ void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data)
 //
 LLUrlEntryPlace::LLUrlEntryPlace()
 {
-	mPattern = boost::regex("((x-grid-location-info://[-\\w\\.]+/region/)|(secondlife://))\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
+	mPattern = boost::regex("((((x-grid-info://)|(x-grid-location-info://))[-\\w\\.]+(:\\d+)?/region/)|(secondlife://))\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
 							boost::regex::perl|boost::regex::icase);
 	mMenuName = "menu_url_slurl.xml";
 	mTooltip = LLTrans::getString("TooltipSLURL");
@@ -1225,7 +1226,7 @@ std::string LLUrlEntryRegion::getLocation(const std::string &url) const
 //
 // LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
 // secondlife:///app/teleport/Ahern/50/50/50/
-// x-grid-location-info://lincoln.lindenlab.com/app/teleport/Ahern/50/50/50/
+// x-grid-info://lincoln.lindenlab.com/app/teleport/Ahern/50/50/50/
 //
 LLUrlEntryTeleport::LLUrlEntryTeleport()
 {
@@ -1299,7 +1300,7 @@ std::string LLUrlEntryTeleport::getLocation(const std::string &url) const
 //
 LLUrlEntrySL::LLUrlEntrySL()
 {
-	mPattern = boost::regex("secondlife://(\\w+)?(:\\d+)?/\\S+",
+	mPattern = boost::regex(X_GRID_OR_SECONDLIFE_HEADER_REGEX "(\\w+)?(:\\d+)?/\\S+",
 							boost::regex::perl|boost::regex::icase);
 	mMenuName = "menu_url_slapp.xml";
 	mTooltip = LLTrans::getString("TooltipSLAPP");
@@ -1316,7 +1317,7 @@ std::string LLUrlEntrySL::getLabel(const std::string &url, const LLUrlLabelCallb
 //
 LLUrlEntrySLLabel::LLUrlEntrySLLabel()
 {
-	mPattern = boost::regex("\\[secondlife://\\S+[ \t]+[^\\]]+\\]",
+	mPattern = boost::regex("\\[" X_GRID_OR_SECONDLIFE_HEADER_REGEX "\\S+[ \t]+[^\\]]+\\]",
 							boost::regex::perl|boost::regex::icase);
 	mMenuName = "menu_url_slapp.xml";
 	mTooltip = LLTrans::getString("TooltipSLAPP");
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 321ea61be3d29f63d03f3e7a3f2ea36bcda1be26..f12cb180c09f63a68b881a7b0bc46599248d2bab 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -404,7 +404,15 @@ WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" '"$INSTDIR\$VIEWER_EXE
 # URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
 # MAINT-8305: On SLURL click, directly invoke the viewer, not the launcher.
 WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
-WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "(default)" "URL:Second Life"
+
+WriteRegStr HKEY_CLASSES_ROOT "x-grid-info" "(default)" "URL:Hypergrid"
+WriteRegStr HKEY_CLASSES_ROOT "x-grid-info" "URL Protocol" ""
+WriteRegStr HKEY_CLASSES_ROOT "x-grid-info\DefaultIcon" "" '"$INSTDIR\$VIEWER_EXE"'
+
+# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
+WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
+
+WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "(default)" "URL:Hypergrid"
 WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "URL Protocol" ""
 WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$VIEWER_EXE"'
 
@@ -677,6 +685,7 @@ DeleteKeys:
   DeleteRegKey SHELL_CONTEXT "SOFTWARE\Classes\x-grid-location-info"
   DeleteRegKey SHELL_CONTEXT "SOFTWARE\Classes\secondlife"
   DeleteRegKey HKEY_CLASSES_ROOT "x-grid-location-info"
+  DeleteRegKey HKEY_CLASSES_ROOT "x-grid-info"
   DeleteRegKey HKEY_CLASSES_ROOT "secondlife"
 
 NoDelete:
diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp
index ba89b14e8d93b06c96a5773b9694cfa811c89967..bbff708494692bb91bebc3e8315827bea37a07b2 100644
--- a/indra/newview/llagentui.cpp
+++ b/indra/newview/llagentui.cpp
@@ -34,6 +34,7 @@
 // Viewer includes
 #include "llagent.h"
 #include "llviewercontrol.h"
+#include "llviewernetwork.h"
 #include "llviewerregion.h"
 #include "llviewerparcelmgr.h"
 #include "llvoavatarself.h"
@@ -52,12 +53,12 @@ void LLAgentUI::buildFullname(std::string& name)
 //static
 void LLAgentUI::buildSLURL(LLSLURL& slurl, const bool escaped /*= true*/)
 {
-      LLSLURL return_slurl;
-      LLViewerRegion *regionp = gAgent.getRegion();
-      if (regionp)
-      {
-		  return_slurl = LLSLURL(regionp->getName(), gAgent.getPositionGlobal());
-      }
+	LLSLURL return_slurl;
+	LLViewerRegion *regionp = gAgent.getRegion();
+	if (regionp)
+	{
+		return_slurl = LLSLURL(regionp->getHGGrid(), regionp->getName(), gAgent.getPositionAgent());
+	}
 	slurl = return_slurl;
 }
 
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 7007ce823e805a972c58ef89140bedad3f72f06f..6620a637f9073641de552f0ec7fde2d098cb3e01 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -63,6 +63,7 @@
 #include "llviewermenu.h"
 #include "llurllineeditorctrl.h"
 #include "llagentui.h"
+#include "llworldmap.h"
 // [RLVa:KB] - Checked: 2010-04-05 (RLVa-1.2.0d)
 #include "rlvhandler.h"
 // [/RLVa:KB]
@@ -747,9 +748,22 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)
 				value["item_type"] = TELEPORT_HISTORY;
 				value["global_pos"] = result->mGlobalPos.getValue();
 				std::string region_name = result->mTitle.substr(0, result->mTitle.find(','));
-				//TODO*: add Surl to teleportitem or parse region name from title
-				value["tooltip"] = LLSLURL(region_name, result->mGlobalPos).getSLURLString();
-				add(result->getTitle(), value); 
+
+				LLSimInfo* sim_info = LLWorldMap::getInstanceFast()->simInfoFromPosGlobal(result->mGlobalPos);
+				if (sim_info)
+				{
+					//TODO*: add Surl to teleportitem or parse region name from title
+					value["tooltip"] = LLSLURL(region_name, sim_info->getLocalPos(result->mGlobalPos)).getSLURLString();
+				}
+				else
+				{
+					//TODO*: add Surl to teleportitem or parse region name from title
+					LLVector3 tempvector(result->mGlobalPos);
+					tempvector[VX] = fmodf(result->mGlobalPos[VX], REGION_WIDTH_METERS);
+					tempvector[VY] = fmodf(result->mGlobalPos[VY], REGION_WIDTH_METERS);
+					value["tooltip"] = LLSLURL(region_name, tempvector).getSLURLString();
+				}
+				add(result->getTitle(), value);
 			}
 			result = std::find_if(result + 1, th_items.end(), boost::bind(
 									&LLLocationInputCtrl::findTeleportItemsByTitle, this,
@@ -1132,7 +1146,7 @@ void LLLocationInputCtrl::changeLocationPresentation()
 		//needs unescaped one
 		LLSLURL slurl;
 		LLAgentUI::buildSLURL(slurl, false);
-		mTextEntry->setText(LLURI::unescape(slurl.getSLURLString()));
+		mTextEntry->setText(slurl.getSLURLString());
 		mTextEntry->selectAll();
 
 		mMaturityButton->setVisible(FALSE);
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index fc891a85058a7bc1972afc26d9d3ef29db61e7a8..a3b514bff29aa48f3b2bd547d6d169e7c8e6c576 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -52,6 +52,7 @@
 #include "llurldispatcher.h"
 #include "llviewerinventory.h"
 #include "llviewermenu.h"
+#include "llviewernetwork.h"
 #include "llviewerparcelmgr.h"
 #include "llworldmapmessage.h"
 #include "llappviewer.h"
@@ -524,6 +525,13 @@ void LLNavigationBar::onLocationSelection()
 	  return;
 	}
 	
+	const std::string& grid = slurl.getGrid();
+	const std::string& current_grid = LLGridManager::getInstance()->getGrid();
+	if (grid != current_grid)
+	{
+		region_name.insert(0, llformat("%s:", grid.c_str()));
+	}
+	
 	// Resolve the region name to its global coordinates.
 	// If resolution succeeds we'll teleport.
 	LLWorldMapMessage::url_callback_t cb = boost::bind(
@@ -551,9 +559,10 @@ void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos)
 	 * At this moment gAgent.getPositionAgent() contains previous coordinates.
 	 * according to EXT-65 agent position is being reseted on each frame.  
 	 */
+	LLVector3 local_agent_pos = gAgent.getPosAgentFromGlobal(global_agent_pos);
 		LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_NO_MATURITY,
-					gAgent.getPosAgentFromGlobal(global_agent_pos));
-	std::string tooltip (LLSLURL(gAgent.getRegion()->getName(), global_agent_pos).getSLURLString());
+			local_agent_pos);
+	std::string tooltip (LLSLURL(gAgent.getRegion()->getName(), local_agent_pos).getSLURLString());
 	
 	LLLocationHistoryItem item (location,
 			global_agent_pos, tooltip,TYPED_REGION_SLURL);// we can add into history only TYPED location
@@ -638,7 +647,7 @@ void LLNavigationBar::onRegionNameResponse(
 		LLVector3d region_pos = from_region_handle(region_handle);
 		LLVector3d global_pos = region_pos + (LLVector3d) local_coords;
 
-		LL_INFOS() << "Teleporting to: " << LLSLURL(region_name,	global_pos).getSLURLString()  << LL_ENDL;
+		LL_INFOS() << "Teleporting to: " << LLSLURL(region_name, local_coords).getSLURLString()  << LL_ENDL;
 		gAgent.teleportViaLocation(global_pos);
 	}
 	else if (gSavedSettings.getBOOL("SearchFromAddressBar"))
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 9157df789fc25d4726da7a4cf7b92ae3ba056cab..7381e8c191bc3f8654a66d5d786391bddc0a5243 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -47,6 +47,7 @@
 #include "lltexturectrl.h"
 #include "llviewerregion.h"
 #include "llhttpconstants.h"
+#include "llworldmap.h"
 
 LLPanelPlaceInfo::LLPanelPlaceInfo()
 :	LLPanel(),
@@ -147,9 +148,17 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLUUID& region_id,
 	if (!region)
 		return;
 
-	mPosRegion.setVec((F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS),
-					  (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS),
-					  (F32)pos_global.mdV[VZ]);
+	const LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
+	if (siminfo)
+	{
+		mPosRegion = siminfo->getLocalPos(pos_global);
+	}
+	else
+	{
+		mPosRegion.setVec((F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS),
+			(F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS),
+			(F32)pos_global.mdV[VZ]);
+	}
 
 	LLSD body;
 	std::string url = region->getCapability("RemoteParcelRequest");
diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp
index 1045d3cf251fcec553c1fce7d35cd57717f0bfea..74e3e777282bc09bba316c58d720be2b4886aa85 100644
--- a/indra/newview/llslurl.cpp
+++ b/indra/newview/llslurl.cpp
@@ -32,6 +32,7 @@
 #include "llpanellogin.h"
 #include "llviewercontrol.h"
 #include "llviewernetwork.h"
+#include "llworldmap.h"
 #include "llfiltersd2xmlrpc.h"
 #include "curl/curl.h"
 // [RLVa:KB] - Checked: 2010-04-05 (RLVa-1.2.0d)
@@ -48,7 +49,8 @@ const char* LLSLURL::SLURL_COM		         = "slurl.com";
 
 const char* LLSLURL::WWW_SLURL_COM				 = "www.slurl.com";
 const char* LLSLURL::MAPS_SECONDLIFE_COM		 = "maps.secondlife.com";
-const char* LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME = "x-grid-location-info";
+const char* LLSLURL::SLURL_X_GRID_INFO_SCHEME	 = "x-grid-info";
+const char* LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME = "x-grid-location-info"; // <- deprecated!
 const char* LLSLURL::SLURL_APP_PATH              = "app";
 const char* LLSLURL::SLURL_REGION_PATH           = "region";
 const char* LLSLURL::SIM_LOCATION_HOME           = "home";
@@ -183,13 +185,14 @@ LLSLURL::LLSLURL(const std::string& slurl)
 		    }
 		}
 		else if((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME) ||
-		   (slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) || 
-		   (slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME))
+			(slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) ||
+			(slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_INFO_SCHEME) ||
+			(slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME))
 		{
-		    // We're dealing with either a Standalone style slurl or slurl.com slurl
-		  if ((slurl_uri.hostName() == LLSLURL::SLURL_COM) ||
-		      (slurl_uri.hostName() == LLSLURL::WWW_SLURL_COM) || 
-		      (slurl_uri.hostName() == LLSLURL::MAPS_SECONDLIFE_COM))
+			// We're dealing with either a Standalone style slurl or slurl.com slurl
+			if ((slurl_uri.hostName() == LLSLURL::SLURL_COM) ||
+				(slurl_uri.hostName() == LLSLURL::WWW_SLURL_COM) ||
+				(slurl_uri.hostName() == LLSLURL::MAPS_SECONDLIFE_COM))
 			{
 				// slurl.com implies maingrid
 				mGrid = MAINGRID;
@@ -209,7 +212,7 @@ LLSLURL::LLSLURL(const std::string& slurl)
 
 				// As it's a Standalone grid/open, we will always have a hostname, as Standalone/open  style
 				// urls are properly formed, unlike the stinky maingrid style
-				mGrid = slurl_uri.hostName();
+				mGrid = slurl_uri.hostNameAndPort();
 			}
 		    if (path_array.size() == 0)
 			{
@@ -290,11 +293,9 @@ LLSLURL::LLSLURL(const std::string& slurl)
 			  
 			  mPosition = LLVector3(path_array); // this construction handles LLSD without all components (values default to 0.f)
 			  if((F32(mPosition[VX]) < 0.f) || 
-                             (mPosition[VX] > REGION_WIDTH_METERS) ||
+                             (mPosition[VX] > 8192.f) ||
 			     (F32(mPosition[VY]) < 0.f) || 
-                             (mPosition[VY] > REGION_WIDTH_METERS) ||
-			     (F32(mPosition[VZ]) < 0.f) || 
-                             (mPosition[VZ] > REGION_HEIGHT_METERS))
+                             (mPosition[VY] > 8192.f))
 			    {
 			      mType = INVALID;
 			      return;
@@ -303,7 +304,7 @@ LLSLURL::LLSLURL(const std::string& slurl)
 			}
 			else
 			{
-				// if x, y and z were not fully passed in, go to the middle of the region.
+				// if x and y were not fully passed in, go to the middle of the region.
 				// teleport will adjust the actual location to make sure you're on the ground
 				// and such
 				mPosition = LLVector3(REGION_WIDTH_METERS/2, REGION_WIDTH_METERS/2, 0);
@@ -333,9 +334,9 @@ LLSLURL::LLSLURL(const std::string& grid,
 {
 	mGrid = grid;
 	mRegion = region;
-	S32 x = ll_round( (F32)fmod( position[VX], (F32)REGION_WIDTH_METERS ) );
-	S32 y = ll_round( (F32)fmod( position[VY], (F32)REGION_WIDTH_METERS ) );
-	S32 z = ll_round( (F32)position[VZ] );
+	S32 x = ll_round(position[VX]);
+	S32 y = ll_round(position[VY]);
+	S32 z = ll_round(position[VZ]);
 	mType = LOCATION;
 	mPosition = LLVector3(x, y, z);
 }
@@ -354,7 +355,7 @@ LLSLURL::LLSLURL(const std::string& grid,
 		 const std::string& region, 
 		 const LLVector3d& global_position)
 {
-	*this = LLSLURL(LLGridManager::getInstance()->getGridId(grid),
+	*this = LLSLURL(grid,
 		  region, LLVector3(global_position.mdV[VX],
 				    global_position.mdV[VY],
 				    global_position.mdV[VZ]));
diff --git a/indra/newview/llslurl.h b/indra/newview/llslurl.h
index b86cf7949ba021e9a921063215f091933ab2a160..3beff26c74c6569278d86a662e1a9e89873e083b 100644
--- a/indra/newview/llslurl.h
+++ b/indra/newview/llslurl.h
@@ -44,6 +44,7 @@ class LLSLURL
 	static const char* WWW_SLURL_COM;
 	static const char* SECONDLIFE_COM;
 	static const char* MAPS_SECONDLIFE_COM;
+	static const char* SLURL_X_GRID_INFO_SCHEME;
 	static const char* SLURL_X_GRID_LOCATION_INFO_SCHEME;
 	static LLSLURL START_LOCATION;
 	static const char* SIM_LOCATION_HOME;
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 04c5666d89f00027fbb51b8b071d75d72bb4db7a..e9f31661c7a12b6b6e47cd8450ce8d3e5917d046 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -183,6 +183,13 @@ bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, const std::string
 		LLPanelLogin::setLocation(slurl);
 		return true;
 	}
+	LLSLURL _slurl = slurl;
+	const std::string& grid = slurl.getGrid();
+	const std::string& current_grid = LLGridManager::getInstance()->getGrid();
+	if (grid != current_grid)
+	{
+		_slurl = LLSLURL(llformat("%s:%s", grid.c_str(), slurl.getRegion().c_str()), slurl.getPosition());
+	}
 
 	// Request a region handle by name
 	LLWorldMapMessage::getInstanceFast()->sendNamedRegionRequest(slurl.getRegion(),
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index b4194afeb37ef71989e0b72c4395b127f003343a..875420a519ccf5ec98afbcd8540fcf62e3f0bed7 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -92,8 +92,8 @@ const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
 const std::string MAIN_GRID_WEB_PROFILE_URL = "https://my.secondlife.com/";
 
 const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/";
-const char* DEFAULT_SLURL_BASE = "https://%s/region/";
-const char* DEFAULT_APP_SLURL_BASE = "x-grid-location-info://%s/app";
+const char* DEFAULT_SLURL_BASE = "x-grid-info://%s/region/";
+const char* DEFAULT_APP_SLURL_BASE = "x-grid-info://%s/app";
 
 const std::string ALCHEMY_UPDATE_SERVICE = "https://app.alchemyviewer.org/update";
 
@@ -344,7 +344,7 @@ bool LLGridManager::addGrid(LLSD& grid_data)
 			}
 			else
 			{
-				LL_WARNS("GridManager")<<"duplicate grid id'"<<grid_id<<"' ignored"<<LL_ENDL;
+				LL_WARNS("GridManager")<<"duplicate grid id '"<<grid_id<<"' ignored"<<LL_ENDL;
 			}
 		}
 		else
@@ -697,17 +697,26 @@ std::string LLGridManager::getGrid(const std::string& grid) const
 	else
 	{
 		// search the grid list for a grid with a matching id
-		for(LLSD::map_const_iterator grid_iter = mGridList.beginMap();
-			grid_name.empty() && grid_iter != mGridList.endMap();
-		    ++grid_iter)
+		for(const auto& grid_pair : mGridList.map())
 		{
-			if (grid_iter->second.has(GRID_ID_VALUE))
+			if (grid_pair.second.has(GRID_ID_VALUE))
 			{
 				if (0 == (LLStringUtil::compareInsensitive(grid,
-														   grid_iter->second[GRID_ID_VALUE].asString())))
+														   grid_pair.second[GRID_ID_VALUE].asString())))
 				{
 					// found a matching label, return this name
-					grid_name = grid_iter->first;
+					grid_name = grid_pair.first;
+					break;
+				}
+			}
+			if (grid_pair.second.has(GRID_GATEKEEPER))
+			{
+				if (0 == (LLStringUtil::compareInsensitive(grid,
+					grid_pair.second[GRID_GATEKEEPER].asString())))
+				{
+					// found a matching label, return this name
+					grid_name = grid_pair.first;
+					break;
 				}
 			}
 		}
@@ -730,14 +739,12 @@ std::string LLGridManager::getGridByAttribute(const std::string& attribute, cons
 {
 	if (attribute.empty() || value.empty()) return LLStringUtil::null;
 	
-	for(LLSD::map_const_iterator grid_iter = mGridList.beginMap();
-		grid_iter != mGridList.endMap();
-	    ++grid_iter)
+	for(const auto& grid_iter : mGridList.map())
 	{
-		if (grid_iter->second.has(attribute)
-			&& LLStringUtil::compareStrings(value, grid_iter->second[attribute].asString()) == 0)
+		if (grid_iter.second.has(attribute)
+			&& LLStringUtil::compareInsensitive(value, grid_iter.second[attribute].asString()) == 0)
 		{
-			return grid_iter->first;
+			return grid_iter.first;
 		}
 	}
 	return LLStringUtil::null;
@@ -1047,7 +1054,6 @@ bool LLGridManager::isSystemGrid(const std::string& grid) const
 	std::string grid_name = getGrid(grid);
 
 	return (   !grid_name.empty()
-			&& mGridList.has(grid_name)
 			&& mGridList[grid_name].has(GRID_IS_SYSTEM_GRID_VALUE)
 			&& mGridList[grid_name][GRID_IS_SYSTEM_GRID_VALUE].asBoolean()
 			);
@@ -1066,7 +1072,7 @@ std::string LLGridManager::getSLURLBase(const std::string& grid) const
 		}
 		else
 		{
-			grid_base = llformat(DEFAULT_SLURL_BASE, grid_name.c_str());
+			grid_base = llformat(DEFAULT_SLURL_BASE, grid.c_str());
 		}
 	}
 	LL_DEBUGS("GridManager")<<"returning '"<<grid_base<<"'"<<LL_ENDL;
@@ -1076,7 +1082,7 @@ std::string LLGridManager::getSLURLBase(const std::string& grid) const
 // build a slurl for the given region within the selected grid
 std::string LLGridManager::getAppSLURLBase(const std::string& grid) const
 {
-	std::string grid_base = "";
+	std::string grid_base;
 	std::string grid_name = getGrid(grid);
 	if(!grid_name.empty())
 	{
@@ -1086,7 +1092,7 @@ std::string LLGridManager::getAppSLURLBase(const std::string& grid) const
 		}
 		else
 		{
-			grid_base = llformat(DEFAULT_APP_SLURL_BASE, grid_name.c_str());
+			grid_base = llformat(DEFAULT_APP_SLURL_BASE, grid.c_str());
 		}
 	}
 	LL_DEBUGS("GridManager")<<"returning '"<<grid_base<<"'"<<LL_ENDL;