diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 72138d8fc914a135b124e2453e663c8f91664e8f..b11e645d2028ecc0ffc707e802485f55518b572b 100755
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -42,7 +42,7 @@
 
 #include <boost/format.hpp> // <alchemy/>
 
-#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
+#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+(:\\d+)?/app)|(secondlife:///app))"
 
 // Utility functions
 std::string localize_slapp_label(const std::string& url, const std::string& full_name);
@@ -1061,7 +1061,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-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");
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 92af029506109e4e21d08d79c9bb3176dc47934d..8a68f00e98f9134eb33d1c88b1623dbdc94d4f6a 100755
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -380,7 +380,19 @@ namespace tut
 
 		testRegex("Standalone Agent Url Multicase with Text", url,
 				  "M x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",
-				  "x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		
+				  "x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+		
+		testRegex("Standalone Agent Url with Port", url,
+				  "x-grid-location-info://my.grid.com:8002/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
+				  "x-grid-location-info://my.grid.com:8002/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+		
+		testRegex("Standalone Agent Url using IP address", url,
+				  "x-grid-location-info://127.0.0.1:9000/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
+				  "x-grid-location-info://127.0.0.1:9000/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+		
+		testRegex("Standalone Agent Url with an ungodly long uri alternate command", url,
+				  "x-grid-location-info://holyshitthisdomainiswaytolongwhywouldyoudothistomewhatthefuckisyourproblem.hi.edu:99999/app/agent/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar",
+				  "x-grid-location-info://holyshitthisdomainiswaytolongwhywouldyoudothistomewhatthefuckisyourproblem.hi.edu:99999/app/agent/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar");
 	}
 
 	template<> template<>
@@ -417,7 +429,15 @@ namespace tut
 		
 		testRegex("Standalone Group Url Multicase ith Text", url,
 				  "M x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",
-				  "x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		
+				  "x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+		
+		testRegex("Standalone Group Url with Port", url,
+				  "x-grid-location-info://my.grid.com:8002/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
+				  "x-grid-location-info://my.grid.com:8002/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+		
+		testRegex("Standalone Group Url using IP address", url,
+				  "x-grid-location-info://127.0.0.1:9000/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
+				  "x-grid-location-info://127.0.0.1:9000/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
 		
 	}
 
@@ -469,7 +489,15 @@ namespace tut
 		
 		testRegex("Standalone All Hands (50,50) [2] with text", url,
 				  "XXX x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50 XXX",
-				  "x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50");		
+				  "x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50");
+		
+		testRegex("Standalone Hippo Pants (50,50) [2] with port and text", url,
+				  "XXX x-grid-location-info://my.grid.com:8002/region/Hippo%20Pants/50/50/50 XXX",
+				  "x-grid-location-info://my.grid.com:8002/region/Hippo%20Pants/50/50/50");
+		
+		testRegex("Standalone Hippo Pants (50,50) [2] with ip address and text", url,
+				  "XXX x-grid-location-info://127.0.0.1:9000/region/Hippo%20Pants/50/50/50 XXX",
+				  "x-grid-location-info://127.0.0.1:9000/region/Hippo%20Pants/50/50/50");
 	}
 
 	template<> template<>
@@ -572,7 +600,16 @@ namespace tut
 		
 		testRegex("Standalone All Hands", url,
 				  "XXX x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50 XXX",
-				  "x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50");		
+				  "x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50");
+		
+		testRegex("Standalone Hippo Pants", url,
+				  "XXX x-grid-location-info://my.grid.com:8002/app/teleport/Hippo%20Pants/50/50/50 XXX",
+				  "x-grid-location-info://my.grid.com:8002/app/teleport/Hippo%20Pants/50/50/50");
+		
+		
+		testRegex("Standalone Hippo Pants with ip address", url,
+				  "XXX x-grid-location-info://127.0.0.1:9000/app/teleport/Hippo%20Pants/50/50/50 XXX",
+				  "x-grid-location-info://127.0.0.1:9000/app/teleport/Hippo%20Pants/50/50/50");
 	}
 
 	template<> template<>
diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp
index 08c50691ff5461a035ceb9c79049ac4ed76d8403..464cc1a1745843dbdd686118abe32466bb6a6633 100755
--- a/indra/newview/llslurl.cpp
+++ b/indra/newview/llslurl.cpp
@@ -197,16 +197,18 @@ LLSLURL::LLSLURL(const std::string& slurl)
 				// SLE SLurls will have the grid hostname in the URL, so only
 				// match http URLs if the hostname matches the grid hostname
 				// (or its a slurl.com or maps.secondlife.com URL).
+				
 				if ((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME ||
 					 slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) &&
-					slurl_uri.hostName() != LLGridManager::getInstance()->getGrid())
+					 (slurl_uri.hostName() != LLGridManager::getInstance()->getGrid() &&
+					  slurl_uri.hostNameAndPort() != LLGridManager::getInstance()->getGrid()))
 				{
 					return;
 				}
 
 				// 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)
 			{
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 4a8fd020d43fb734fc7856c446615ad6fef1de6a..ea6d2282a817f4ec47733011bd178661414890db 100755
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -71,7 +71,9 @@ const std::string GRID_GATEKEEPER = "gatekeeper";
 // we need to continue to support existing forms, as slurls
 // are shared between viewers that may not understand newer
 // forms.
+/// slurl base for grid slurls
 const std::string GRID_SLURL_BASE = "slurl_base";
+/// slurl base for grid slapp links
 const std::string GRID_APP_SLURL_BASE = "app_slurl_base";
 
 const std::string DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/";
@@ -562,6 +564,11 @@ void LLGridManager::gridInfoResponderCallback(LLSD& grid, LLXMLNodePtr root_node
 			grid[GRID_SLURL_BASE] = node->getTextContents();
 			LL_DEBUGS("GridManager") << "[\"slurl_base\"]: " << grid[GRID_SLURL_BASE] << LL_ENDL;
 		}
+		else if (node->hasName("app_slurl_base"))
+		{
+			grid[GRID_APP_SLURL_BASE] = node->getTextContents();
+			LL_DEBUGS("GridManager") << "[\"app_slurl_base\"]: " << grid[GRID_APP_SLURL_BASE] << LL_ENDL;
+		}
 	}
 	
 	if (addGrid(grid))
@@ -656,6 +663,18 @@ std::string LLGridManager::getGrid(const std::string& grid) const
 	return grid_name;
 }
 
+std::string LLGridManager::getGridByProbing(const std::string& identifier) const
+{
+	std::string grid = LLStringUtil::null;
+	grid = getGridByAttribute(GRID_VALUE, identifier);
+	if (!grid.empty()) return grid;
+	grid = getGridByAttribute(GRID_ID_VALUE, identifier);
+	if (!grid.empty()) return grid;
+	grid = getGridByAttribute(GRID_GATEKEEPER, identifier);
+	if (!grid.empty()) return grid;
+	return grid;
+}
+
 std::string LLGridManager::getGridByAttribute(const std::string& attribute, const std::string& value) const
 {
 	if (attribute.empty() || value.empty()) return LLStringUtil::null;
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index f1b6e79f7059545142c87fadda52ec915e94542b..0a71a5b912f1c23fa49152eed794120b5946dca9 100755
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -90,6 +90,9 @@ class LLGridManager : public LLSingleton<LLGridManager>
 	/// Return the name of a grid, given either its name or its id
 	std::string getGrid(const std::string& grid) const;
 	
+	/// Returns the grid value by probing attributes
+	std::string getGridByProbing(const std::string& identifier) const;
+	
 	/// Return the grid value by attribute
 	std::string getGridByAttribute(const std::string& attribute, const std::string& value) const;
 
diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp
index c95579901195a47fa8b31854f2431a29034c0fc4..49d51093fffd777a737c1ebb7acb48e31c8ea158 100755
--- a/indra/newview/tests/llslurl_test.cpp
+++ b/indra/newview/tests/llslurl_test.cpp
@@ -123,6 +123,19 @@ const char *gSampleGridFile =
 	"      <key>credential_type</key><string>agent</string>"
 	"      <key>grid_login_id</key><string>MyGrid</string>"
 	"    </map>"
+	"    <key>my.stupidgrid.com:8002</key>"
+	"    <map>"
+	"      <key>helper_uri</key><string>https://my.stupidgrid.com/helpers/</string>"
+	"      <key>label</key><string>My Stupid Grid</string>"
+	"      <key>login_page</key><string>my.stupidgrid.com/loginpage</string>"
+	"      <key>login_uri</key>"
+	"      <array>"
+	"        <string>my.stupidgrid.com:8002/</string>"
+	"      </array>"
+	"      <key>keyname</key><string>my.stupidgrid.com:8002</string>"
+	"      <key>credential_type</key><string>agent</string>"
+	"      <key>grid_login_id</key><string>My Stupid Grid</string>"
+	"    </map>"
 	"  </map>"
 	"</llsd>"
 	;
@@ -302,6 +315,7 @@ namespace tut
 					  "https://my.grid.com/region/my%20region/1/2/3");
 
 	}
+	
 	// Accessors
 	template<> template<>
 	void slurlTestObject::test<3>()
@@ -323,7 +337,52 @@ namespace tut
 		slurl = LLSLURL("http://my.grid.com:8002/region/my%20region/1/2/3");
 		ensure_equals("login string", slurl.getLoginString(), "uri:my region&amp;1&amp;2&amp;3");
 		ensure_equals("location string", slurl.getLocationString(), "my region/1/2/3");
-		ensure_equals("grid", slurl.getGrid(), "my.grid.com");
+		ensure_equals("grid", slurl.getGrid(), "my.grid.com:8002");
+		ensure_equals("region", slurl.getRegion(), "my region");
+		ensure_equals("position", slurl.getPosition(), LLVector3(1, 2, 3));
+	}
+	
+	// x-grid-location-info
+	template<> template<>
+	void slurlTestObject::test<4>()
+	{
+		llofstream gridfile(TEST_FILENAME);
+		gridfile << gSampleGridFile;
+		gridfile.close();
+		
+		LLGridManager::getInstance()->initialize(TEST_FILENAME);
+		
+		LLGridManager::getInstance()->setGridChoice("my.grid.com");
+		LLSLURL slurl = LLSLURL("x-grid-location-info://my.grid.com/app/foo/bar?12345");
+		ensure_equals("app", slurl.getType(), LLSLURL::APP);
+		ensure_equals("appcmd", slurl.getAppCmd(), "foo");
+		ensure_equals("apppath", slurl.getAppPath().size(), 1);
+		ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar");
+		ensure_equals("appquery", slurl.getAppQuery(), "12345");
+		ensure_equals("grid1", slurl.getGrid(), "my.grid.com");
+		
+		slurl = LLSLURL("x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+		ensure_equals("app", slurl.getType(), LLSLURL::APP);
+		ensure_equals("appcmd", slurl.getAppCmd(), "agent");
+		ensure_equals("apppath", slurl.getAppPath().size(), 2);
+		ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "0e346d8b-4433-4d66-a6b0-fd37083abc4c");
+		ensure_equals("apppath3", slurl.getAppPath()[1].asString(), "about");
+		ensure_equals("grid1", slurl.getGrid(), "lincoln.lindenlab.com");
+		
+		LLGridManager::getInstance()->setGridChoice("my.stupidgrid.com:8002");
+		slurl = LLSLURL("x-grid-location-info://my.stupidgrid.com:8002/app/foo/bar/baz?12345");
+		ensure_equals("app", slurl.getType(), LLSLURL::APP);
+		ensure_equals("appcmd", slurl.getAppCmd(), "foo");
+		ensure_equals("apppath", slurl.getAppPath().size(), 2);
+		ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar");
+		ensure_equals("apppath3", slurl.getAppPath()[1].asString(), "baz");
+		ensure_equals("appquery", slurl.getAppQuery(), "12345");
+		ensure_equals("grid1", slurl.getGrid(), "my.stupidgrid.com:8002");
+		
+		slurl = LLSLURL("x-grid-location-info://my.stupidgrid.com:8002/region/my%20region/1/2/3");
+		ensure_equals("login string", slurl.getLoginString(), "uri:my region&amp;1&amp;2&amp;3");
+		ensure_equals("location string", slurl.getLocationString(), "my region/1/2/3");
+		ensure_equals("grid", slurl.getGrid(), "my.stupidgrid.com:8002");
 		ensure_equals("region", slurl.getRegion(), "my region");
 		ensure_equals("position", slurl.getPosition(), LLVector3(1, 2, 3));
 	}