diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 128d67d73d0831cae97c53ec08f20c8a99f0f965..50d149152303fe85e776497909b54650662fce8d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -275,6 +275,7 @@ set(viewer_SOURCE_FILES
     lllogchat.cpp
     llloginhandler.cpp
     lllogininstance.cpp
+    llmachineid.cpp
     llmanip.cpp
     llmaniprotate.cpp
     llmanipscale.cpp
@@ -792,6 +793,7 @@ set(viewer_HEADER_FILES
     lllogchat.h
     llloginhandler.h
     lllogininstance.h
+    llmachineid.h
     llmanip.h
     llmaniprotate.h
     llmanipscale.h
@@ -1841,7 +1843,7 @@ if (LL_TESTS)
   )
 
     LL_ADD_INTEGRATION_TEST(llsechandler_basic
-     llsechandler_basic.cpp
+    llsechandler_basic.cpp
     "${test_libs}"
     )
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 475a075d7e3ce2580901e9705df307abd7823bff..ca9830e1a081467d0e666e14a2756eeee1755087 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -195,6 +195,7 @@
 
 // Include for security api initialization
 #include "llsecapi.h"
+#include "llmachineid.h"
 
 // *FIX: These extern globals should be cleaned up.
 // The globals either represent state/config/resource-storage of either 
@@ -619,6 +620,7 @@ bool LLAppViewer::init()
     // *NOTE:Mani - LLCurl::initClass is not thread safe. 
     // Called before threads are created.
     LLCurl::initClass();
+    LLMachineID::init();
 
     initThreads();
     writeSystemInfo();
diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..53243e9807b442c62c839168583d03b1629a5e2f
--- /dev/null
+++ b/indra/newview/llmachineid.cpp
@@ -0,0 +1,269 @@
+/** 
+ * @file llmachineid.cpp
+ * @brief retrieves unique machine ids
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "lluuid.h"
+#include "llmachineid.h"
+#if	LL_WINDOWS
+#define _WIN32_DCOM
+#include <iostream>
+using namespace std;
+#include <comdef.h>
+#include <Wbemidl.h>
+#endif
+unsigned char static_unique_id[] =  {0,0,0,0,0,0};
+bool static has_static_unique_id = false;
+
+// get an unique machine id.
+// NOT THREAD SAFE - do before setting up threads.
+// MAC Address doesn't work for Windows 7 since the first returned hardware MAC address changes with each reboot,  Go figure??
+
+S32 LLMachineID::init()
+{
+    memset(static_unique_id,0,sizeof(static_unique_id));
+    S32 ret_code = 0;
+#if	LL_WINDOWS
+# pragma comment(lib, "wbemuuid.lib")
+        size_t len = sizeof(static_unique_id);
+
+        // algorithm to detect BIOS serial number found at:
+        // http://msdn.microsoft.com/en-us/library/aa394077%28VS.85%29.aspx
+        // we can't use the MAC address since on Windows 7, the first returned MAC address changes with every reboot.
+
+
+        HRESULT hres;
+
+        // Step 1: --------------------------------------------------
+        // Initialize COM. ------------------------------------------
+
+        hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
+        if (FAILED(hres))
+        {
+            LL_DEBUGS("AppInit") << "Failed to initialize COM library. Error code = 0x"   << hex << hres << LL_ENDL;
+            return 1;                  // Program has failed.
+        }
+
+        // Step 2: --------------------------------------------------
+        // Set general COM security levels --------------------------
+        // Note: If you are using Windows 2000, you need to specify -
+        // the default authentication credentials for a user by using
+        // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
+        // parameter of CoInitializeSecurity ------------------------
+
+        hres =  CoInitializeSecurity(
+            NULL, 
+            -1,                          // COM authentication
+            NULL,                        // Authentication services
+            NULL,                        // Reserved
+            RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
+            RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
+            NULL,                        // Authentication info
+            EOAC_NONE,                   // Additional capabilities 
+            NULL                         // Reserved
+            );
+
+                          
+        if (FAILED(hres))
+        {
+            LL_DEBUGS("AppInit") << "Failed to initialize security. Error code = 0x"  << hex << hres << LL_ENDL;
+            CoUninitialize();
+            return 1;                    // Program has failed.
+        }
+        
+        // Step 3: ---------------------------------------------------
+        // Obtain the initial locator to WMI -------------------------
+
+        IWbemLocator *pLoc = NULL;
+
+        hres = CoCreateInstance(
+            CLSID_WbemLocator,             
+            0, 
+            CLSCTX_INPROC_SERVER, 
+            IID_IWbemLocator, (LPVOID *) &pLoc);
+     
+        if (FAILED(hres))
+        {
+            LL_DEBUGS("AppInit") << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << LL_ENDL;
+            CoUninitialize();
+            return 1;                 // Program has failed.
+        }
+
+        // Step 4: -----------------------------------------------------
+        // Connect to WMI through the IWbemLocator::ConnectServer method
+
+        IWbemServices *pSvc = NULL;
+    	
+        // Connect to the root\cimv2 namespace with
+        // the current user and obtain pointer pSvc
+        // to make IWbemServices calls.
+        hres = pLoc->ConnectServer(
+             _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
+             NULL,                    // User name. NULL = current user
+             NULL,                    // User password. NULL = current
+             0,                       // Locale. NULL indicates current
+             NULL,                    // Security flags.
+             0,                       // Authority (e.g. Kerberos)
+             0,                       // Context object 
+             &pSvc                    // pointer to IWbemServices proxy
+             );
+        
+        if (FAILED(hres))
+        {
+            LL_DEBUGS("AppInit") << "Could not connect. Error code = 0x"  << hex << hres << LL_ENDL;
+            pLoc->Release();     
+            CoUninitialize();
+            return 1;                // Program has failed.
+        }
+
+        LL_DEBUGS("AppInit") << "Connected to ROOT\\CIMV2 WMI namespace" << LL_ENDL;
+
+
+        // Step 5: --------------------------------------------------
+        // Set security levels on the proxy -------------------------
+
+        hres = CoSetProxyBlanket(
+           pSvc,                        // Indicates the proxy to set
+           RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
+           RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
+           NULL,                        // Server principal name 
+           RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
+           RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
+           NULL,                        // client identity
+           EOAC_NONE                    // proxy capabilities 
+        );
+
+        if (FAILED(hres))
+        {
+            LL_DEBUGS("AppInit") << "Could not set proxy blanket. Error code = 0x"   << hex << hres << LL_ENDL;
+            pSvc->Release();
+            pLoc->Release();     
+            CoUninitialize();
+            return 1;               // Program has failed.
+        }
+
+        // Step 6: --------------------------------------------------
+        // Use the IWbemServices pointer to make requests of WMI ----
+
+        // For example, get the name of the operating system
+        IEnumWbemClassObject* pEnumerator = NULL;
+        hres = pSvc->ExecQuery(
+            bstr_t("WQL"), 
+            bstr_t("SELECT * FROM Win32_OperatingSystem"),
+            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
+            NULL,
+            &pEnumerator);
+        
+        if (FAILED(hres))
+        {
+            LL_DEBUGS("AppInit") << "Query for operating system name failed." << " Error code = 0x"  << hex << hres << LL_ENDL;
+            pSvc->Release();
+            pLoc->Release();
+            CoUninitialize();
+            return 1;               // Program has failed.
+        }
+
+        // Step 7: -------------------------------------------------
+        // Get the data from the query in step 6 -------------------
+     
+        IWbemClassObject *pclsObj = NULL;
+        ULONG uReturn = 0;
+       
+        while (pEnumerator)
+        {
+            HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
+                &pclsObj, &uReturn);
+
+            if(0 == uReturn)
+            {
+                break;
+            }
+
+            VARIANT vtProp;
+
+            // Get the value of the Name property
+            hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
+            LL_DEBUGS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL;
+            // use characters in the returned Serial Number to create a byte array of size len
+            BSTR serialNumber ( vtProp.bstrVal);
+            unsigned int j = 0;
+            while( vtProp.bstrVal[j] != 0)
+            {
+                for (unsigned int i = 0; i < len; i++)
+                {
+                    if (vtProp.bstrVal[j] == 0)
+                        break;
+                    
+                    static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]);
+                    j++;
+                }
+            }
+            VariantClear(&vtProp);
+
+            pclsObj->Release();
+            pclsObj = NULL;
+            break;
+        }
+
+        // Cleanup
+        // ========
+        
+        if (pSvc)
+            pSvc->Release();
+        if (pLoc)
+            pLoc->Release();
+        if (pEnumerator)
+            pEnumerator->Release();
+        CoUninitialize();
+        ret_code=0;
+#else
+        unsigned char * staticPtr = (unsigned char *)(&static_unique_id[0]);
+        ret_code = LLUUID::getNodeID(staticPtr);
+#endif
+        has_static_unique_id = true;
+        return ret_code;
+}
+
+
+S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
+{
+    if (has_static_unique_id)
+    {
+        memcpy ( unique_id, &static_unique_id, len);
+        LL_DEBUGS("AppInit") << "UniqueID: " << unique_id[0] << unique_id[1]<< unique_id[2] << unique_id[3] << unique_id[4] << unique_id [5] << LL_ENDL;
+        return 1;
+    }
+    return 0;
+}
+
+
+
+
diff --git a/indra/newview/llmachineid.h b/indra/newview/llmachineid.h
new file mode 100644
index 0000000000000000000000000000000000000000..8160309b471ea9dc0cf23d11a6bed9f289298210
--- /dev/null
+++ b/indra/newview/llmachineid.h
@@ -0,0 +1,56 @@
+/** 
+ * @file llmachineid.h
+ * @brief retrieves unique machine ids
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMACHINEID_H
+#define LL_LLMACHINEID_H
+
+
+class LLMachineID 
+{
+public:
+	LLMachineID();
+	virtual	~LLMachineID();
+    static S32 getUniqueID(unsigned char *unique_id, size_t len);
+    static S32 init();
+
+protected:
+
+private:
+
+
+};
+
+
+
+
+
+#endif // LL_LLMACHINEID_H
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 0009f7203aa08b7d7fdff411bda05e5a76e02634..c8dae024cf41c578ed21f952ce4919f697756752 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -1164,7 +1164,8 @@ void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe)
 
 void LLPanelLogin::updateLoginPanelLinks()
 {
-	LLSD grid_data = LLGridManager::getInstance()->getGridInfo();
+	LLSD grid_data;
+	LLGridManager::getInstance()->getGridInfo(grid_data);
 	bool system_grid = grid_data.has(GRID_IS_SYSTEM_GRID_VALUE);
 	
 	// need to call through sInstance, as it's called from onSelectServer, which
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index 1caeec5b04c865b3e5700c36405e4d2c36e0ab84..9e636f38c0cd747b97e439c191b48a8a76d85c83 100644
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
@@ -124,7 +124,7 @@ int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
 		// we rely on libcurl to validate the hostname, as libcurl does more extensive validation
 		// leaving our hostname validation call mechanism for future additions with respect to
 		// OS native (Mac keyring, windows CAPI) validation.
-		chain->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), store, validation_params);
+		store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
 	}
 	catch (LLCertValidationTrustException& cert_exception)
 	{
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index 59a1e1eff09bb8592ee98e841450acb77d76d419..5a1a3879d4ccb392d0d1921d3bcd561fb763aabf 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -154,7 +154,7 @@ class LLCertificate : public LLRefCount
 	
 	// return an LLSD object containing information about the certificate
 	// such as its name, signature, expiry time, serial number
-	virtual LLSD getLLSD() const=0; 
+	virtual void getLLSD(LLSD& llsd)=0; 
 	
 	// return an openSSL X509 struct for the certificate
 	virtual X509* getOpenSSLX509() const=0;
@@ -231,6 +231,18 @@ class LLCertificateVector : public LLRefCount
 	virtual LLPointer<LLCertificate> erase(iterator cert)=0;	
 };
 
+// class LLCertificateChain
+// Class representing a chain of certificates in order, with the 
+// first element being the child cert.
+class LLCertificateChain : virtual public LLCertificateVector
+{	
+	
+public:
+	LLCertificateChain() {}
+	
+	virtual ~LLCertificateChain() {}
+	
+};
 
 // class LLCertificateStore
 // represents a store of certificates, typically a store of root CA
@@ -250,30 +262,17 @@ class LLCertificateStore : virtual public LLCertificateVector
 	
 	// return the store id
 	virtual std::string storeId() const=0;
-};
-
-// class LLCertificateChain
-// Class representing a chain of certificates in order, with the 
-// first element being the child cert.
-class LLCertificateChain : virtual public LLCertificateVector
-{	
-
-public:
-	LLCertificateChain() {}
 	
-	virtual ~LLCertificateChain() {}
-
 	// validate a certificate chain given the params.
 	// Will throw exceptions on error
 	
 	virtual void validate(int validation_policy,
-						  LLPointer<LLCertificateStore> ca_store,
+						  LLPointer<LLCertificateChain> cert_chain,
 						  const LLSD& validation_params) =0;
+	
 };
 
 
-
-
 inline
 bool operator==(const LLCertificateVector::iterator& _lhs, const LLCertificateVector::iterator& _rhs)
 {
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index c4c13ccdca293a869efcb99cc96960fa86755512..e191e50c4b78322e967d8ca95bc80ee6fa11449f 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -52,6 +52,7 @@ LLS * By copying, modifying or distributing this software, you acknowledge
 #include <iostream>
 #include <iomanip>
 #include <time.h>
+#include "llmachineid.h"
 
 
 
@@ -85,7 +86,6 @@ LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert)
 	{
 		throw LLInvalidCertificate(this);
 	}
-	_initLLSD();
 }
 
 
@@ -96,7 +96,6 @@ LLBasicCertificate::LLBasicCertificate(X509* pCert)
 		throw LLInvalidCertificate(this);
 	}	
 	mCert = X509_dup(pCert);
-	_initLLSD();
 }
 
 LLBasicCertificate::~LLBasicCertificate() 
@@ -150,9 +149,13 @@ std::vector<U8> LLBasicCertificate::getBinary() const
 }
 
 
-LLSD LLBasicCertificate::getLLSD() const
+void LLBasicCertificate::getLLSD(LLSD &llsd)
 {
-	return mLLSDInfo;
+	if (mLLSDInfo.isUndefined())
+	{
+		_initLLSD();
+	}
+	llsd = mLLSDInfo;
 }
 
 // Initialize the LLSD info for the certificate
@@ -516,8 +519,9 @@ LLBasicCertificateVector::iterator LLBasicCertificateVector::find(const LLSD& pa
 		cert++)
 	{
 
-			found= TRUE;
-		LLSD cert_info = (*cert)->getLLSD();
+		found= TRUE;
+		LLSD cert_info;
+		(*cert)->getLLSD(cert_info);
 			for (LLSD::map_const_iterator param = params.beginMap();
 			 param != params.endMap();
 			 param++)
@@ -543,7 +547,8 @@ LLBasicCertificateVector::iterator LLBasicCertificateVector::find(const LLSD& pa
 void  LLBasicCertificateVector::insert(iterator _iter, 
 				       LLPointer<LLCertificate> cert)
 {
-	LLSD cert_info = cert->getLLSD();
+	LLSD cert_info;
+	cert->getLLSD(cert_info);
 	if (cert_info.isMap() && cert_info.has(CERT_SHA1_DIGEST))
 	{
 		LLSD existing_cert_info = LLSD::emptyMap();
@@ -695,7 +700,8 @@ LLBasicCertificateChain::LLBasicCertificateChain(const X509_STORE_CTX* store)
 		while(untrusted_certs.size() > 0)
 		{
 			LLSD find_data = LLSD::emptyMap();
-			LLSD cert_data = current->getLLSD();
+			LLSD cert_data;
+			current->getLLSD(cert_data);
 			// we simply build the chain via subject/issuer name as the
 			// client should not have passed in multiple CA's with the same 
 			// subject name.  If they did, it'll come out in the wash during
@@ -854,12 +860,13 @@ bool _LLSDArrayIncludesValue(const LLSD& llsd_set, LLSD llsd_value)
 }
 
 void _validateCert(int validation_policy,
-				  const LLPointer<LLCertificate> cert,
+				  LLPointer<LLCertificate> cert,
 				  const LLSD& validation_params,
 				  int depth)
 {
 
-	LLSD current_cert_info = cert->getLLSD();		
+	LLSD current_cert_info;
+	cert->getLLSD(current_cert_info);		
 	// check basic properties exist in the cert
 	if(!current_cert_info.has(CERT_SUBJECT_NAME) || !current_cert_info.has(CERT_SUBJECT_NAME_STRING))
 	{
@@ -947,8 +954,9 @@ bool _verify_signature(LLPointer<LLCertificate> parent,
 					   LLPointer<LLCertificate> child)
 {
 	bool verify_result = FALSE; 
-	LLSD cert1 = parent->getLLSD();
-	LLSD cert2 = child->getLLSD();
+	LLSD cert1, cert2;
+	parent->getLLSD(cert1);
+	child->getLLSD(cert2);
 	X509 *signing_cert = parent->getOpenSSLX509();
 	X509 *child_cert = child->getOpenSSLX509();
 	if((signing_cert != NULL) && (child_cert != NULL))
@@ -983,6 +991,7 @@ bool _verify_signature(LLPointer<LLCertificate> parent,
 	return verify_result;
 }
 
+
 // validate the certificate chain against a store.
 // There are many aspects of cert validatioin policy involved in
 // trust validation.  The policies in this validation algorithm include
@@ -997,17 +1006,17 @@ bool _verify_signature(LLPointer<LLCertificate> parent,
 // and verify the last cert is in the certificate store, or points
 // to a cert in the store.  It validates whether any cert in the chain
 // is trusted in the store, even if it's not the last one.
-void LLBasicCertificateChain::validate(int validation_policy,
-									   LLPointer<LLCertificateStore> ca_store,
+void LLBasicCertificateStore::validate(int validation_policy,
+									   LLPointer<LLCertificateChain> cert_chain,
 									   const LLSD& validation_params)
 {
 
-	if(size() < 1)
+	if(cert_chain->size() < 1)
 	{
 		throw LLCertException(NULL, "No certs in chain");
 	}
-	iterator current_cert = begin();
-	LLSD 	current_cert_info = (*current_cert)->getLLSD();
+	iterator current_cert = cert_chain->begin();
+	LLSD 	current_cert_info;
 	LLSD validation_date;
 	if (validation_params.has(CERT_VALIDATION_DATE))
 	{
@@ -1016,6 +1025,7 @@ void LLBasicCertificateChain::validate(int validation_policy,
 
 	if (validation_policy & VALIDATION_POLICY_HOSTNAME)
 	{
+		(*current_cert)->getLLSD(current_cert_info);
 		if(!validation_params.has(CERT_HOSTNAME))
 		{
 			throw LLCertException((*current_cert), "No hostname passed in for validation");			
@@ -1025,7 +1035,7 @@ void LLBasicCertificateChain::validate(int validation_policy,
 			throw LLInvalidCertificate((*current_cert));				
 		}
 		
-		LL_INFOS("SECAPI") << "Validating the hostname " << validation_params[CERT_HOSTNAME].asString() << 
+		LL_DEBUGS("SECAPI") << "Validating the hostname " << validation_params[CERT_HOSTNAME].asString() << 
 		     "against the cert CN " << current_cert_info[CERT_SUBJECT_NAME][CERT_NAME_CN].asString() << LL_ENDL;
 		if(!_cert_hostname_wildcard_match(validation_params[CERT_HOSTNAME].asString(),
 										  current_cert_info[CERT_SUBJECT_NAME][CERT_NAME_CN].asString()))
@@ -1034,16 +1044,50 @@ void LLBasicCertificateChain::validate(int validation_policy,
 													(*current_cert));
 		}
 	}
-	
 
+	// check the cache of already validated certs
+	X509* cert_x509 = (*current_cert)->getOpenSSLX509();
+	if(!cert_x509)
+	{
+		throw LLInvalidCertificate((*current_cert));			
+	}
+	std::string sha1_hash((const char *)cert_x509->sha1_hash, SHA_DIGEST_LENGTH);
+	t_cert_cache::iterator cache_entry = mTrustedCertCache.find(sha1_hash);
+	if(cache_entry != mTrustedCertCache.end())
+	{
+		LL_DEBUGS("SECAPI") << "Found cert in cache" << LL_ENDL;	
+		// this cert is in the cache, so validate the time.
+		if (validation_policy & VALIDATION_POLICY_TIME)
+		{
+			LLDate validation_date(time(NULL));
+			if(validation_params.has(CERT_VALIDATION_DATE))
+			{
+				validation_date = validation_params[CERT_VALIDATION_DATE];
+			}
+			
+			if((validation_date < cache_entry->second.first) ||
+			   (validation_date > cache_entry->second.second))
+			{
+				throw LLCertValidationExpirationException((*current_cert), validation_date);
+			}
+		}
+		// successfully found in cache
+		return;
+	}
+	if(current_cert_info.isUndefined())
+	{
+		(*current_cert)->getLLSD(current_cert_info);
+	}
+	LLDate from_time = current_cert_info[CERT_VALID_FROM].asDate();
+	LLDate to_time = current_cert_info[CERT_VALID_TO].asDate();
 	int depth = 0;
 	LLPointer<LLCertificate> previous_cert;
 	// loop through the cert chain, validating the current cert against the next one.
-	while(current_cert != end())
+	while(current_cert != cert_chain->end())
 	{
 		
 		int local_validation_policy = validation_policy;
-		if(current_cert == begin())
+		if(current_cert == cert_chain->begin())
 		{
 			// for the child cert, we don't validate CA stuff
 			local_validation_policy &= ~(VALIDATION_POLICY_CA_KU | 
@@ -1065,23 +1109,23 @@ void LLBasicCertificateChain::validate(int validation_policy,
 					  depth);
 		
 		// look for a CA in the CA store that may belong to this chain.
-		LLSD cert_llsd = (*current_cert)->getLLSD();
 		LLSD cert_search_params = LLSD::emptyMap();		
 		// is the cert itself in the store?
-		cert_search_params[CERT_SHA1_DIGEST] = cert_llsd[CERT_SHA1_DIGEST];
-		LLCertificateStore::iterator found_store_cert = ca_store->find(cert_search_params);
-		if(found_store_cert != ca_store->end())
+		cert_search_params[CERT_SHA1_DIGEST] = current_cert_info[CERT_SHA1_DIGEST];
+		LLCertificateStore::iterator found_store_cert = find(cert_search_params);
+		if(found_store_cert != end())
 		{
+			mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time);
 			return;
 		}
 		
 		// is the parent in the cert store?
 			
 		cert_search_params = LLSD::emptyMap();
-		cert_search_params[CERT_SUBJECT_NAME_STRING] = cert_llsd[CERT_ISSUER_NAME_STRING];
-		if (cert_llsd.has(CERT_AUTHORITY_KEY_IDENTIFIER))
+		cert_search_params[CERT_SUBJECT_NAME_STRING] = current_cert_info[CERT_ISSUER_NAME_STRING];
+		if (current_cert_info.has(CERT_AUTHORITY_KEY_IDENTIFIER))
 		{
-			LLSD cert_aki = cert_llsd[CERT_AUTHORITY_KEY_IDENTIFIER];
+			LLSD cert_aki = current_cert_info[CERT_AUTHORITY_KEY_IDENTIFIER];
 			if(cert_aki.has(CERT_AUTHORITY_KEY_IDENTIFIER_ID))
 			{
 				cert_search_params[CERT_SUBJECT_KEY_IDENTFIER] = cert_aki[CERT_AUTHORITY_KEY_IDENTIFIER_ID];
@@ -1091,11 +1135,10 @@ void LLBasicCertificateChain::validate(int validation_policy,
 				cert_search_params[CERT_SERIAL_NUMBER] = cert_aki[CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL];
 			}
 		}
-		found_store_cert = ca_store->find(cert_search_params);
+		found_store_cert = find(cert_search_params);
 		
-		if(found_store_cert != ca_store->end())
+		if(found_store_cert != end())
 		{
-			LLSD foo = (*found_store_cert)->getLLSD();
 			// validate the store cert against the depth
 			_validateCert(validation_policy & VALIDATION_POLICY_CA_BASIC_CONSTRAINTS,
 						  (*found_store_cert),
@@ -1109,19 +1152,24 @@ void LLBasicCertificateChain::validate(int validation_policy,
 				throw LLCertValidationInvalidSignatureException(*current_cert);
 			}			
 			// successfully validated.
+			mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time);		
 			return;
 		}
 		previous_cert = (*current_cert);
 		current_cert++;
-			   depth++;
+		depth++;
+		if(current_cert != cert_chain->end())
+		{
+			(*current_cert)->getLLSD(current_cert_info);
+		}
 	}
 	if (validation_policy & VALIDATION_POLICY_TRUSTED)
 	{
-		LLPointer<LLCertificate> untrusted_ca_cert = (*this)[size()-1];
 		// we reached the end without finding a trusted cert.
-		throw LLCertValidationTrustException((*this)[size()-1]);
+		throw LLCertValidationTrustException((*cert_chain)[cert_chain->size()-1]);
 
 	}
+	mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time);	
 }
 
 
@@ -1159,7 +1207,7 @@ void LLSecAPIBasicHandler::init()
 														"CA.pem");
 		
 		
-		LL_INFOS("SECAPI") << "Loading certificate store from " << store_file << LL_ENDL;
+		LL_DEBUGS("SECAPI") << "Loading certificate store from " << store_file << LL_ENDL;
 		mStore = new LLBasicCertificateStore(store_file);
 		
 		// grab the application CA.pem file that contains the well-known certs shipped
@@ -1199,9 +1247,9 @@ void LLSecAPIBasicHandler::_readProtectedData()
 		U8 buffer[BUFFER_READ_SIZE];
 		U8 decrypted_buffer[BUFFER_READ_SIZE];
 		int decrypted_length;	
-		unsigned char MACAddress[MAC_ADDRESS_BYTES];
-		LLUUID::getNodeID(MACAddress);
-		LLXORCipher cipher(MACAddress, MAC_ADDRESS_BYTES);
+		unsigned char unique_id[MAC_ADDRESS_BYTES];
+        LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
+		LLXORCipher cipher(unique_id, sizeof(unique_id));
 
 		// read in the salt and key
 		protected_data_stream.read((char *)salt, STORE_SALT_SIZE);
@@ -1285,9 +1333,9 @@ void LLSecAPIBasicHandler::_writeProtectedData()
 		EVP_CIPHER_CTX ctx;
 		EVP_CIPHER_CTX_init(&ctx);
 		EVP_EncryptInit(&ctx, EVP_rc4(), salt, NULL);
-		unsigned char MACAddress[MAC_ADDRESS_BYTES];
-		LLUUID::getNodeID(MACAddress);
-		LLXORCipher cipher(MACAddress, MAC_ADDRESS_BYTES);
+		unsigned char unique_id[MAC_ADDRESS_BYTES];
+        LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
+		LLXORCipher cipher(unique_id, sizeof(unique_id));
 		cipher.encrypt(salt, STORE_SALT_SIZE);
 		protected_data_stream.write((const char *)salt, STORE_SALT_SIZE);
 
@@ -1469,7 +1517,7 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool sav
 	{
 		credential["authenticator"] = cred->getAuthenticator();
 	}
-	LL_INFOS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
+	LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
 	setProtectedData("credential", cred->getGrid(), credential);
 	//*TODO: If we're saving Agni credentials, should we write the
 	// credentials to the legacy password.dat/etc?
@@ -1505,9 +1553,9 @@ std::string LLSecAPIBasicHandler::_legacyLoadPassword()
 	}
 	
 	// Decipher with MAC address
-	unsigned char MACAddress[MAC_ADDRESS_BYTES];
-	LLUUID::getNodeID(MACAddress);
-	LLXORCipher cipher(MACAddress, 6);
+	unsigned char unique_id[MAC_ADDRESS_BYTES];
+    LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
+	LLXORCipher cipher(unique_id, sizeof(unique_id));
 	cipher.decrypt(&buffer[0], buffer.size());
 	
 	return std::string((const char*)&buffer[0], buffer.size());
diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h
index 407e74ad0096bae169cda4ba927e2b05765cecde..356ea7efcb7e51d1dcae04eaef6e7700fe42ecf3 100644
--- a/indra/newview/llsechandler_basic.h
+++ b/indra/newview/llsechandler_basic.h
@@ -59,12 +59,13 @@ class LLBasicCertificate : public LLCertificate
 	
 	virtual std::string getPem() const;
 	virtual std::vector<U8> getBinary() const;
-	virtual LLSD getLLSD() const;
+	virtual void getLLSD(LLSD &llsd);
 
 	virtual X509* getOpenSSLX509() const;
 	
 	// set llsd elements for testing
 	void setLLSD(const std::string name, const LLSD& value) { mLLSDInfo[name] = value; }
+
 protected:
 
 	// certificates are stored as X509 objects, as validation and
@@ -175,8 +176,21 @@ class LLBasicCertificateStore : virtual public LLBasicCertificateVector, public
 	// return the store id
 	virtual std::string storeId() const;
 	
+	// validate a certificate chain against a certificate store, using the
+	// given validation policy.
+	virtual void validate(int validation_policy,
+						  LLPointer<LLCertificateChain> ca_chain,
+						  const LLSD& validation_params);
+	
 protected:
-	std::vector<LLPointer<LLCertificate> >mCerts;
+	std::vector<LLPointer<LLCertificate> >            mCerts;
+	
+	// cache of cert sha1 hashes to from/to date pairs, to improve
+	// performance of cert trust.  Note, these are not the CA certs,
+	// but the certs that have been validated against this store.
+	typedef std::map<std::string, std::pair<LLDate, LLDate> > t_cert_cache;
+	t_cert_cache mTrustedCertCache;
+	
 	std::string mFilename;
 };
 
@@ -191,11 +205,6 @@ class LLBasicCertificateChain : virtual public LLBasicCertificateVector, public
 	
 	virtual ~LLBasicCertificateChain() {}
 	
-	// validate a certificate chain against a certificate store, using the
-	// given validation policy.
-	virtual void validate(int validation_policy,
-						  LLPointer<LLCertificateStore> ca_store,
-						  const LLSD& validation_params);
 };
 
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index d8b5618d8f85903155693b3c1ff4780808e08b13..6418551517aee96bebeeda1f17bf575785f6fc4d 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2732,7 +2732,8 @@ LLSD transform_cert_args(LLPointer<LLCertificate> cert)
 {
 	LLSD args = LLSD::emptyMap();
 	std::string value;
-	LLSD cert_info = cert->getLLSD();
+	LLSD cert_info;
+	cert->getLLSD(cert_info);
 	// convert all of the elements in the cert into                                        
 	// args for the xml dialog, so we have flexability to                                  
 	// display various parts of the cert by only modifying                                 
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 9efa6c410838fa998e1d1003a5645dfe582d8cd6..cbaa7248a28cafcfdd7d6ffd859fd9f739649d0b 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -215,7 +215,8 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL&
 		LLSD args;
 		args["SLURL"] = slurl.getLocationString();
 		args["CURRENT_GRID"] = LLGridManager::getInstance()->getGridLabel();
-		LLSD grid_info = LLGridManager::getInstance()->getGridInfo(slurl.getGrid());
+		LLSD grid_info;
+		LLGridManager::getInstance()->getGridInfo(slurl.getGrid(), grid_info);
 		
 		if(grid_info.has(GRID_LABEL_VALUE))
 		{
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index c76eee80f79cd293f07b87c060f0dee180a9aedf..fec112b9e7e6c3b9235a6c1f0fee3add1c6cc512 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -226,11 +226,11 @@ void LLGridManager::initialize(const std::string& grid_file)
 					LLSD grid = grid_itr->second;
 					// TODO:  Make sure gridfile specified label is not 
 					// a system grid label
-					LL_INFOS("GridManager") << "reading: " << key_name << LL_ENDL;
+					LL_DEBUGS("GridManager") << "reading: " << key_name << LL_ENDL;
 					if (mGridList.has(key_name) &&
 						mGridList[key_name].has(GRID_IS_SYSTEM_GRID_VALUE))
 					{
-						LL_INFOS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL;
+						LL_DEBUGS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL;
 						// If the system grid does exist in the grids file, and it's marked as a favorite, set it as a favorite.
 						if(grid_itr->second.has(GRID_IS_FAVORITE_VALUE) && grid_itr->second[GRID_IS_FAVORITE_VALUE].asBoolean() )
 						{
@@ -242,7 +242,7 @@ void LLGridManager::initialize(const std::string& grid_file)
 						try
 						{
 							addGrid(grid);
-							LL_INFOS("GridManager") << "Added grid: " << key_name << LL_ENDL;
+							LL_DEBUGS("GridManager") << "Added grid: " << key_name << LL_ENDL;
 						}
 						catch (...)
 						{
@@ -260,84 +260,60 @@ void LLGridManager::initialize(const std::string& grid_file)
 	std::string cmd_line_grid = gSavedSettings.getString("CmdLineGridChoice");
 	if(!cmd_line_grid.empty())
 	{
+		// try to find the grid assuming the command line parameter is
+		// the case-insensitive 'label' of the grid.  ie 'Agni'
 		mGrid = getGridByLabel(cmd_line_grid);
+		if(mGrid.empty())
+		{
+			// if we couldn't find it, assume the
+			// requested grid is the actual grid 'name' or index,
+			// which would be the dns name of the grid (for non
+			// linden hosted grids)
+			// If the grid isn't there, that's ok, as it will be
+			// automatically added later.
+			mGrid = cmd_line_grid;
+		}
+		
+	}
+	else
+	{
+		// if a grid was not passed in via the command line, grab it from the CurrentGrid setting.
+		// if there's no current grid, that's ok as it'll be either set by the value passed
+		// in via the login uri if that's specified, or will default to maingrid
+		mGrid = gSavedSettings.getString("CurrentGrid");
 	}
-	LL_INFOS("GridManager") << "Grid Name: " << mGrid << LL_ENDL;		
 	
-	// If a command line login URI was passed in, so we should add the command
-	// line grid to the list of grids
-
-	LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI");
-	if (cmd_line_login_uri.isString())
+	if(mGrid.empty())
 	{
-		LL_INFOS("GridManager") << "adding cmd line login uri" << LL_ENDL;
-		// grab the other related URI values
-		std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI");
-		std::string cmd_line_login_page = gSavedSettings.getString("LoginPage");
+		// no grid was specified so default to maingrid
+		LL_DEBUGS("GridManager") << "Setting grid to MAINGRID as no grid has been specified " << LL_ENDL;
+		mGrid = MAINGRID;
 		
-		// we've a cmd line login, so add a grid for the command line,
-		// overwriting any existing grids
-		LLSD grid = LLSD::emptyMap();
-		grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
-		grid[GRID_LOGIN_URI_VALUE].append(cmd_line_login_uri);
-		LL_INFOS("GridManager") << "cmd line login uri: " << cmd_line_login_uri.asString() << LL_ENDL;
-		LLURI uri(cmd_line_login_uri.asString());
-		if (mGrid.empty())
-		{
-			// if a grid name was not passed in via the command line,
-			// then set the grid name based on the hostname of the 
-			// login uri
-			mGrid = uri.hostName();
-		}
-
-		grid[GRID_VALUE] = mGrid;
-
-		if (mGridList.has(mGrid) && mGridList[mGrid].has(GRID_LABEL_VALUE))
-		{
-			grid[GRID_LABEL_VALUE] = mGridList[mGrid][GRID_LABEL_VALUE];
-		}
-		else
-		{
-			grid[GRID_LABEL_VALUE] = mGrid;			
-		}
-		if(!cmd_line_helper_uri.empty())
-		{
-			grid[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri;
-		}
-
-		if(!cmd_line_login_page.empty())
-		{
-			grid[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page;
-		}
-		// if the login page, helper URI value, and so on are not specified,
-		// add grid will generate them.
-
-		// Also, we will override a system grid if values are passed in via the command
-		// line, for testing.  These values will not be remembered though.
-		if (mGridList.has(mGrid) && mGridList[mGrid].has(GRID_IS_SYSTEM_GRID_VALUE))
-		{
-			grid[GRID_IS_SYSTEM_GRID_VALUE] = TRUE;
-		}
-		addGrid(grid);
 	}
 	
-	// if a grid was not passed in via the command line, grab it from the CurrentGrid setting.
-	if (mGrid.empty())
+	// generate a 'grid list' entry for any command line parameter overrides
+	// or setting overides that we'll add to the grid list or override
+	// any grid list entries with.
+	LLSD grid = LLSD::emptyMap();	
+	
+	if(mGridList.has(mGrid))
 	{
-
-		mGrid = gSavedSettings.getString("CurrentGrid");
+		grid = mGridList[mGrid];
 	}
-
-	if (mGrid.empty() || !mGridList.has(mGrid))
+	else
 	{
-		// the grid name was empty, or the grid isn't actually in the list, then set it to the
-		// appropriate default.
-		LL_INFOS("GridManager") << "Resetting grid as grid name " << mGrid << " is not in the list" << LL_ENDL;
-		mGrid = MAINGRID;
+		grid[GRID_VALUE] = mGrid;
+		// add the grid with the additional values, or update the
+		// existing grid if it exists with the given values
+		addGrid(grid);		
 	}
-	LL_INFOS("GridManager") << "Selected grid is " << mGrid << LL_ENDL;		
-	gSavedSettings.setString("CurrentGrid", mGrid);
 
+	LL_DEBUGS("GridManager") << "Selected grid is " << mGrid << LL_ENDL;		
+	setGridChoice(mGrid);
+	if(mGridList[mGrid][GRID_LOGIN_URI_VALUE].isArray())
+	{
+		llinfos << "is array" << llendl;
+	}
 }
 
 LLGridManager::~LLGridManager()
@@ -345,6 +321,36 @@ LLGridManager::~LLGridManager()
 	saveFavorites();
 }
 
+void LLGridManager::getGridInfo(const std::string &grid, LLSD& grid_info)
+{
+	
+	grid_info = mGridList[grid]; 
+	
+	// override any grid data with the command line info.
+	
+	LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI");
+	if (cmd_line_login_uri.isString())
+	{	
+		grid_info[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
+		grid_info[GRID_LOGIN_URI_VALUE].append(cmd_line_login_uri);
+	}
+	
+	// override the helper uri if it was passed in
+	std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI");
+	if(!cmd_line_helper_uri.empty())
+	{
+		grid_info[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri;	
+	}
+	
+	// override the login page if it was passed in
+	std::string cmd_line_login_page = gSavedSettings.getString("LoginPage");
+	if(!cmd_line_login_page.empty())
+	{
+		grid_info[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page;
+	}	
+}
+
+
 //
 // LLGridManager::addGrid - add a grid to the grid list, populating the needed values
 // if they're not populated yet.
@@ -401,7 +407,7 @@ void LLGridManager::addGrid(LLSD& grid_data)
 			grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT);
 		}
 		
-		LL_INFOS("GridManager") << "ADDING: " << grid << LL_ENDL;
+		LL_DEBUGS("GridManager") << "ADDING: " << grid << LL_ENDL;
 		mGridList[grid] = grid_data;		
 	}
 }
@@ -467,6 +473,7 @@ std::map<std::string, std::string> LLGridManager::getKnownGrids(bool favorite_on
 	return result;
 }
 
+
 void LLGridManager::setGridChoice(const std::string& grid)
 {
 	// Set the grid choice based on a string.
@@ -477,35 +484,37 @@ void LLGridManager::setGridChoice(const std::string& grid)
 
 	// loop through.  We could do just a hash lookup but we also want to match
 	// on label
-	for(LLSD::map_iterator grid_iter = mGridList.beginMap();
-		grid_iter != mGridList.endMap();
-		grid_iter++) 
+	std::string grid_name = grid;
+	if(!mGridList.has(grid_name))
 	{
-		if((grid == grid_iter->first) || 
-		   (grid == grid_iter->second[GRID_LABEL_VALUE].asString()))
-		{
-			mGrid = grid_iter->second[GRID_VALUE].asString();
-			gSavedSettings.setString("CurrentGrid", grid_iter->second[GRID_VALUE]);			
-			return; 
-
-		}
+		// case insensitive
+		grid_name = getGridByLabel(grid);
+	}
+	
+	if(grid_name.empty())
+	{
+		// the grid was not in the list of grids.
+		LLSD grid_data = LLSD::emptyMap();
+		grid_data[GRID_VALUE] = grid;
+		addGrid(grid_data);		
 	}
-	LLSD grid_data = LLSD::emptyMap();
-	grid_data[GRID_VALUE] = grid;
-	addGrid(grid_data);
 	mGrid = grid;
 	gSavedSettings.setString("CurrentGrid", grid);
 }
 
-std::string LLGridManager::getGridByLabel( const std::string &grid_label)
+std::string LLGridManager::getGridByLabel( const std::string &grid_label, bool case_sensitive)
 {
 	for(LLSD::map_iterator grid_iter = mGridList.beginMap();
 		grid_iter != mGridList.endMap();
 		grid_iter++) 
 	{
-		if (grid_iter->second.has(GRID_LABEL_VALUE) && (grid_iter->second[GRID_LABEL_VALUE].asString() == grid_label))
+		if (grid_iter->second.has(GRID_LABEL_VALUE))
 		{
-			return grid_iter->first;
+			if (0 == (case_sensitive?LLStringUtil::compareStrings(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString()):
+				LLStringUtil::compareInsensitive(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString())))
+			{
+				return grid_iter->first;
+			}
 		}
 	}
 	return std::string();
@@ -514,6 +523,12 @@ std::string LLGridManager::getGridByLabel( const std::string &grid_label)
 void LLGridManager::getLoginURIs(std::vector<std::string>& uris)
 {
 	uris.clear();
+	LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI");
+	if (cmd_line_login_uri.isString())
+	{	
+		uris.push_back(cmd_line_login_uri);
+		return;
+	}
 	for (LLSD::array_iterator llsd_uri = mGridList[mGrid][GRID_LOGIN_URI_VALUE].beginArray();
 		 llsd_uri != mGridList[mGrid][GRID_LOGIN_URI_VALUE].endArray();
 		 llsd_uri++)
@@ -522,6 +537,28 @@ void LLGridManager::getLoginURIs(std::vector<std::string>& uris)
 	}
 }
 
+std::string LLGridManager::getHelperURI() 
+{
+	std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI");
+	if(!cmd_line_helper_uri.empty())
+	{
+		return cmd_line_helper_uri;	
+	}
+	return mGridList[mGrid][GRID_HELPER_URI_VALUE];
+}
+
+std::string LLGridManager::getLoginPage() 
+{
+	// override the login page if it was passed in
+	std::string cmd_line_login_page = gSavedSettings.getString("LoginPage");
+	if(!cmd_line_login_page.empty())
+	{
+		return cmd_line_login_page;
+	}	
+	
+	return mGridList[mGrid][GRID_LOGIN_PAGE_VALUE];
+}
+
 bool LLGridManager::isInProductionGrid()
 {
 	// *NOTE:Mani This used to compare GRID_INFO_AGNI to gGridChoice,
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index 0271e7a7a559305d134e869fe308f4091ddfe34c..8c3a15b7cf08bcaea86a51c2bde3a1b69b35c116 100644
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -89,17 +89,7 @@ class LLGridManager : public LLSingleton<LLGridManager>
 	// by default only return the user visible grids
 	std::map<std::string, std::string> getKnownGrids(bool favorites_only=FALSE);
 	
-	LLSD getGridInfo(const std::string& grid)
-	{
-		if(mGridList.has(grid))
-		{
-			return mGridList[grid];
-		}
-		else
-		{
-			return LLSD();
-		}
-	}
+	void getGridInfo(const std::string& grid, LLSD &grid_info);
 	
 	// current grid management
 
@@ -112,8 +102,8 @@ class LLGridManager : public LLSingleton<LLGridManager>
 	std::string getGridLabel() { return mGridList[mGrid][GRID_LABEL_VALUE]; } 	
 	std::string getGrid() const { return mGrid; }
 	void getLoginURIs(std::vector<std::string>& uris);
-	std::string getHelperURI() {return mGridList[mGrid][GRID_HELPER_URI_VALUE];}
-	std::string getLoginPage() {return mGridList[mGrid][GRID_LOGIN_PAGE_VALUE];}
+	std::string getHelperURI();
+	std::string getLoginPage();
 	std::string getGridLoginID() { return mGridList[mGrid][GRID_ID_VALUE]; }	
 	std::string getLoginPage(const std::string& grid) { return mGridList[grid][GRID_LOGIN_PAGE_VALUE]; }
 	void        getLoginIdentifierTypes(LLSD& idTypes) { idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES]; }
@@ -125,9 +115,9 @@ class LLGridManager : public LLSingleton<LLGridManager>
 	std::string getAppSLURLBase(const std::string& grid);
 	std::string getAppSLURLBase() { return getAppSLURLBase(mGrid); }	
 	
-	LLSD getGridInfo() { return mGridList[mGrid]; }
+	void getGridInfo(LLSD &grid_info) { getGridInfo(mGrid, grid_info); }
 	
-	std::string getGridByLabel( const std::string &grid_label);
+	std::string getGridByLabel( const std::string &grid_label, bool case_sensitive = false);
 	
 	bool isSystemGrid(const std::string& grid) 
 	{ 
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index bc7f8ec854a02a9839ce1fe54110e6b807a01321..a8ac0c0c90e93631ea16b7ae99933c17c9a43d2b 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -248,7 +248,8 @@ int LLXMLRPCTransaction::Impl::_sslCertVerifyCallback(X509_STORE_CTX *ctx, void
 	validation_params[CERT_HOSTNAME] = uri.hostName();
 	try
 	{
-		chain->validate(VALIDATION_POLICY_SSL, store, validation_params);
+		// don't validate hostname.  Let libcurl do it instead.  That way, it'll handle redirects
+		store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
 	}
 	catch (LLCertValidationTrustException& cert_exception)
 	{
@@ -512,7 +513,6 @@ void LLXMLRPCTransaction::Impl::setStatus(EStatus status,
 				// Usually this means that there's a problem with the login server,
 				// not with the client.  Direct user to status page.
 				mStatusMessage = LLTrans::getString("server_is_down");
-
 				mStatusURI = "http://secondlife.com/status/";
 		}
 	}
@@ -547,7 +547,7 @@ void LLXMLRPCTransaction::Impl::setCurlStatus(CURLcode code)
 				"Often this means that your computer\'s clock is set incorrectly.\n"
 				"Please go to Control Panels and make sure the time and date\n"
 				"are set correctly.\n"
-				"\n"
+				"Also check that your network and firewall are set up correctly.\n"
 				"If you continue to receive this error, please go\n"
 				"to the Support section of the SecondLife.com web site\n"
 				"and report the problem.";
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 404b87ec1c99cb275276f2419b4dc7a289f5c8a8..75de75a14db96ef3730272a5af6eec835a31e80d 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6182,6 +6182,37 @@ Avatar '[NAME]' entered appearance mode.
 Avatar '[NAME]' left appearance mode.
   </notification>
 
+    <notification
+   icon="alertmodal.tga"
+   name="NoConnect"
+   type="alertmodal">
+        We're having trouble connecting using [PROTOCOL] [HOSTID].
+        Please check your network and firewall setup.
+        <form name="form">
+            <button
+               default="true"
+               index="0"
+               name="OK"
+               text="OK"/>
+        </form>
+    </notification>
+
+    <notification
+          icon="alertmodal.tga"
+          name="NoVoiceConnect"
+          type="alertmodal">
+        We're having trouble connecting your voiceserver using [HOSTID].
+        Voice communications will not be available.
+        Please check your network and firewall setup.
+        <form name="form">
+            <button
+               default="true"
+               index="0"
+               name="OK"
+               text="OK"/>
+        </form>
+    </notification>
+
   <notification
    icon="notifytip.tga"
    name="AvatarRezLeftNotification"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index e57b30185d80f2ac2e775ddd4fadf1ae620a1164..ba646189bfa60e477de00fb8b5b6327689145454 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3180,7 +3180,8 @@ Abuse Report</string>
   <string name="server_is_down">
 	Despite our best efforts, something unexpected has gone wrong.
 
-	Please check secondlife.com/status to see if there is a known problem with the service.
+	Please check secondlife.com/status to see if there is a known problem with the service.  
+        If you continue to experience problems, please check your network and firewall setup.
   </string>
 
   </strings>
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index fd680b24f0dd7e871438b3f2f8a53e8525ea1194..fa9fff3ac978f8670374622d5e5be46e3db3a8d4 100644
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -54,7 +54,7 @@
 #include <openssl/asn1.h>
 #include <openssl/rand.h>
 #include <openssl/err.h>
-
+#include "../llmachineid.h"
 
 #define ensure_throws(str, exc_type, cert, func, ...) \
 try \
@@ -115,6 +115,15 @@ void LLCredential::authenticatorType(std::string &idType)
 LLControlGroup gSavedSettings("test");
 unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {77,21,46,31,89,2};
 
+
+S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
+{
+	memcpy(unique_id, gMACAddress, len);
+	return 1;
+}
+S32 LLMachineID::init() { return 1; }
+	
+
 // -------------------------------------------------------------------------------------------
 // TUT
 // -------------------------------------------------------------------------------------------
@@ -129,6 +138,7 @@ namespace tut
 
 		sechandler_basic_test()
 		{
+            LLMachineID::init();
 			OpenSSL_add_all_algorithms();
 			OpenSSL_add_all_ciphers();
 			OpenSSL_add_all_digests();	
@@ -328,7 +338,8 @@ namespace tut
 		
 		ensure_equals("Der Format is correct", memcmp(buffer, mDerFormat.c_str(), mDerFormat.length()), 0);
 		
-		LLSD llsd_cert = test_cert->getLLSD();
+		LLSD llsd_cert;
+		test_cert->getLLSD(llsd_cert);
 		std::ostringstream llsd_value;
 		llsd_value << LLSDOStreamer<LLSDNotationFormatter>(llsd_cert) << std::endl;
 		std::string llsd_cert_str = llsd_value.str();
@@ -376,8 +387,6 @@ namespace tut
 	void sechandler_basic_test_object::test<2>()
 
 	{
-		unsigned char MACAddress[MAC_ADDRESS_BYTES];
-		LLUUID::getNodeID(MACAddress);
 		
 		std::string protected_data = "sUSh3wj77NG9oAMyt3XIhaej3KLZhLZWFZvI6rIGmwUUOmmelrRg0NI9rkOj8ZDpTPxpwToaBT5u"
 		"GQhakdaGLJznr9bHr4/6HIC1bouKj4n2rs4TL6j2WSjto114QdlNfLsE8cbbE+ghww58g8SeyLQO"
@@ -390,7 +399,9 @@ namespace tut
 
 		LLXORCipher cipher(gMACAddress, MAC_ADDRESS_BYTES);
 		cipher.decrypt(&binary_data[0], 16);
-		LLXORCipher cipher2(MACAddress, MAC_ADDRESS_BYTES);
+		unsigned char unique_id[MAC_ADDRESS_BYTES];
+        LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
+		LLXORCipher cipher2(unique_id, sizeof(unique_id));
 		cipher2.encrypt(&binary_data[0], 16);
 		std::ofstream temp_file("sechandler_settings.tmp", std::ofstream::binary);
 		temp_file.write((const char *)&binary_data[0], binary_data.size());
@@ -571,11 +582,11 @@ namespace tut
 		int length = apr_base64_decode_len(hashed_password.c_str());
 		std::vector<char> decoded_password(length);
 		apr_base64_decode(&decoded_password[0], hashed_password.c_str());
-		unsigned char MACAddress[MAC_ADDRESS_BYTES];
-		LLUUID::getNodeID(MACAddress);
 		LLXORCipher cipher(gMACAddress, MAC_ADDRESS_BYTES);
 		cipher.decrypt((U8*)&decoded_password[0], length);
-		LLXORCipher cipher2(MACAddress, MAC_ADDRESS_BYTES);
+		unsigned char unique_id[MAC_ADDRESS_BYTES];
+		LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
+		LLXORCipher cipher2(unique_id, sizeof(unique_id));
 		cipher2.encrypt((U8*)&decoded_password[0], length);
 		llofstream password_file("test_password.dat", std::ofstream::binary);
 		password_file.write(&decoded_password[0], length); 
@@ -950,31 +961,38 @@ namespace tut
 
 		test_chain->add(new LLBasicCertificate(mX509IntermediateCert));
 
-		test_chain->validate(0, test_store, validation_params);
+		test_store->validate(0, test_chain, validation_params);
 
 		// add the root certificate to the chain and revalidate
 		test_chain->add(new LLBasicCertificate(mX509RootCert));	
-		test_chain->validate(0, test_store, validation_params);
+		test_store->validate(0, test_chain, validation_params);
 
 		// add the child cert at the head of the chain, and revalidate (3 deep chain)
 		test_chain->insert(test_chain->begin(), new LLBasicCertificate(mX509ChildCert));
-		test_chain->validate(0, test_store, validation_params);
+		test_store->validate(0, test_chain, validation_params);
 
 		// basic failure cases
 		test_chain = new LLBasicCertificateChain(NULL);
-		//validate with only the child cert
+		//validate with only the child cert in chain, but child cert was previously
+		// trusted
 		test_chain->add(new LLBasicCertificate(mX509ChildCert));
+		
+		// validate without the trust flag.
+		test_store->validate(VALIDATION_POLICY_TRUSTED, test_chain, validation_params);	
+		
+		// Validate with child cert but no parent, and no parent in CA store
+		test_store = new LLBasicCertificateStore("mycertstore.pem");
 		ensure_throws("no CA, with only a child cert", 
 					  LLCertValidationTrustException, 
 					  (*test_chain)[0],
-					  test_chain->validate, 
+					  test_store->validate, 
 					  VALIDATION_POLICY_TRUSTED, 
-					  test_store, 
+					  test_chain, 
 					  validation_params);
 
 
 		// validate without the trust flag.
-		test_chain->validate(0, test_store, validation_params);		
+		test_store->validate(0, test_chain, validation_params);		
 
 		// clear out the store
 		test_store = new LLBasicCertificateStore("mycertstore.pem");
@@ -983,18 +1001,19 @@ namespace tut
 		ensure_throws("no CA, with child and intermediate certs", 
 					  LLCertValidationTrustException, 
 					  (*test_chain)[1],
-					  test_chain->validate, 
+					  test_store->validate, 
 					  VALIDATION_POLICY_TRUSTED, 
-					  test_store, 
+					  test_chain, 
 					  validation_params);
 		// validate without the trust flag
-		test_chain->validate(0, test_store, validation_params);
+		test_store->validate(0, test_chain, validation_params);
 
 		// Test time validity
-		LLSD child_info = (*test_chain)[0]->getLLSD();
+		LLSD child_info;
+		((*test_chain)[0])->getLLSD(child_info);
 		validation_params = LLSD::emptyMap();
 		validation_params[CERT_VALIDATION_DATE] = LLDate(child_info[CERT_VALID_FROM].asDate().secondsSinceEpoch() + 1.0);  
-		test_chain->validate(VALIDATION_POLICY_TIME, test_store, validation_params);
+		test_store->validate(VALIDATION_POLICY_TIME, test_chain, validation_params);
 
 		validation_params = LLSD::emptyMap();		
 		validation_params[CERT_VALIDATION_DATE] = child_info[CERT_VALID_FROM].asDate();
@@ -1005,9 +1024,9 @@ namespace tut
 		ensure_throws("Child cert not yet valid" , 
 					  LLCertValidationExpirationException, 
 					  (*test_chain)[0],
-					  test_chain->validate, 
+					  test_store->validate, 
 					  VALIDATION_POLICY_TIME, 
-					  test_store, 
+					  test_chain, 
 					  validation_params);	
 		validation_params = LLSD::emptyMap();		
 		validation_params[CERT_VALIDATION_DATE] = LLDate(child_info[CERT_VALID_TO].asDate().secondsSinceEpoch() + 1.0);
@@ -1016,9 +1035,9 @@ namespace tut
 		ensure_throws("Child cert expired", 
 					  LLCertValidationExpirationException, 
 					  (*test_chain)[0],
-					  test_chain->validate, 
+					  test_store->validate, 
 					  VALIDATION_POLICY_TIME, 
-					  test_store, 
+					  test_chain, 
 					  validation_params);
 
 		// test SSL KU
@@ -1026,17 +1045,18 @@ namespace tut
 		test_chain = new LLBasicCertificateChain(NULL);
 		test_chain->add(new LLBasicCertificate(mX509ChildCert));
 		test_chain->add(new LLBasicCertificate(mX509IntermediateCert));
-		test_chain->validate(VALIDATION_POLICY_SSL_KU, test_store, validation_params);	
+		test_store->validate(VALIDATION_POLICY_SSL_KU, test_chain, validation_params);	
 
 		test_chain = new LLBasicCertificateChain(NULL);
 		test_chain->add(new LLBasicCertificate(mX509TestCert));
 
+		test_store = new LLBasicCertificateStore("mycertstore.pem");		
 		ensure_throws("Cert doesn't have ku", 
 					  LLCertKeyUsageValidationException, 
 					  (*test_chain)[0],
-					  test_chain->validate, 
+					  test_store->validate, 
 					  VALIDATION_POLICY_SSL_KU, 
-					  test_store, 
+					  test_chain, 
 					  validation_params);
 		
 		// test sha1RSA validation
@@ -1044,7 +1064,7 @@ namespace tut
 		test_chain->add(new LLBasicCertificate(mSha1RSATestCert));	
 		test_chain->add(new LLBasicCertificate(mSha1RSATestCA));
 
-		test_chain->validate(0, test_store, validation_params);	
+		test_store->validate(0, test_chain, validation_params);	
 	}
 	
 };
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index d819b445645546ba9b9cd36f169423c6bf0fb717..5fba5eb69c348fe394fb9e3f3e9b30cc754eb335 100644
--- a/indra/newview/tests/llviewernetwork_test.cpp
+++ b/indra/newview/tests/llviewernetwork_test.cpp
@@ -148,7 +148,8 @@ namespace tut
 					  known_grids[std::string("util.agni.lindenlab.com")], std::string("Agni"));
 		ensure_equals("None exists", known_grids[""], "None");
 		
-		LLSD grid = LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com");
+		LLSD grid;
+		LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid);
 		ensure("Grid info for agni is a map", grid.isMap());
 		ensure_equals("name is correct for agni", 
 					  grid[GRID_VALUE].asString(), std::string("util.agni.lindenlab.com"));
@@ -190,7 +191,8 @@ namespace tut
 	
 		
 		// assure Agni doesn't get overwritten
-		LLSD grid = LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com");
+		LLSD grid;
+		LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid);
 
 		ensure_equals("Agni grid label was not modified by grid file", 
 					  grid[GRID_LABEL_VALUE].asString(), std::string("Agni"));
@@ -215,7 +217,7 @@ namespace tut
 		
 		ensure_equals("Grid file adds to name<->label map", 
 					  known_grids["grid1"], std::string("mylabel"));
-		grid = LLGridManager::getInstance()->getGridInfo("grid1");
+		LLGridManager::getInstance()->getGridInfo("grid1", grid);
 		ensure_equals("grid file grid name is set",
 					  grid[GRID_VALUE].asString(), std::string("grid1"));
 		ensure_equals("grid file label is set", 
@@ -244,35 +246,20 @@ namespace tut
 	template<> template<>
 	void viewerNetworkTestObject::test<3>()
 	{	
-		gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi";
-		
+		// USE --grid command line
+		// initialize with a known grid
+		LLSD grid;
+		gCmdLineGridChoice = "Aditi";
 		LLGridManager::getInstance()->initialize("grid_test.xml");
 		// with single login uri specified.
 		std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
-		ensure_equals("adding a command line grid increases known grid size", 
-					  known_grids.size(), 24);
-		ensure_equals("Command line grid is added to the list of grids", 
-					  known_grids["my.login.uri"], std::string("my.login.uri"));
-		LLSD grid = LLGridManager::getInstance()->getGridInfo("my.login.uri");
-		ensure_equals("Command line grid name is set",
-					  grid[GRID_VALUE].asString(), std::string("my.login.uri"));
-		ensure_equals("Command line grid label is set", 
-					  grid[GRID_LABEL_VALUE].asString(), std::string("my.login.uri"));
-		ensure("Command line grid login uri is an array",
-			   grid[GRID_LOGIN_URI_VALUE].isArray());
-		ensure_equals("Command line grid login uri is set",
-					  grid[GRID_LOGIN_URI_VALUE][0].asString(), 
-					  std::string("https://my.login.uri/cgi-bin/login.cgi"));
-		ensure_equals("Command line grid helper uri is set",
-					  grid[GRID_HELPER_URI_VALUE].asString(), 
-					  std::string("https://my.login.uri/helpers/"));
-		ensure_equals("Command line grid login page is set",
-					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
-					  std::string("http://my.login.uri/app/login/"));
-		ensure("Command line grid favorite is set",
-			   !grid.has(GRID_IS_FAVORITE_VALUE));
-		ensure("Command line grid isn't a system grid",
-			   !grid.has(GRID_IS_SYSTEM_GRID_VALUE));		
+		ensure_equals("Using a known grid via command line doesn't increase number of known grids", 
+					  known_grids.size(), 23);
+		ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Aditi"));
+		// initialize with a known grid in lowercase
+		gCmdLineGridChoice = "agni";
+		LLGridManager::getInstance()->initialize("grid_test.xml");
+		ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Agni"));		
 		
 		// now try a command line with a custom grid identifier
 		gCmdLineGridChoice = "mycustomgridchoice";		
@@ -282,7 +269,7 @@ namespace tut
 					  known_grids.size(), 24);
 		ensure_equals("Custom Command line grid is added to the list of grids", 
 					  known_grids["mycustomgridchoice"], std::string("mycustomgridchoice"));
-		grid = LLGridManager::getInstance()->getGridInfo("mycustomgridchoice");
+		LLGridManager::getInstance()->getGridInfo("mycustomgridchoice", grid);
 		ensure_equals("Custom Command line grid name is set",
 					  grid[GRID_VALUE].asString(), std::string("mycustomgridchoice"));
 		ensure_equals("Custom Command line grid label is set", 
@@ -290,27 +277,166 @@ namespace tut
 		ensure("Custom Command line grid login uri is an array",
 			   grid[GRID_LOGIN_URI_VALUE].isArray());
 		ensure_equals("Custom Command line grid login uri is set",
+					  grid[GRID_LOGIN_URI_VALUE][0].asString(), 
+					  std::string("https://mycustomgridchoice/cgi-bin/login.cgi"));
+		ensure_equals("Custom Command line grid helper uri is set",
+					  grid[GRID_HELPER_URI_VALUE].asString(), 
+					  std::string("https://mycustomgridchoice/helpers/"));
+		ensure_equals("Custom Command line grid login page is set",
+					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
+					  std::string("http://mycustomgridchoice/app/login/"));
+	}
+	
+	// validate override of login uri with cmd line
+	template<> template<>
+	void viewerNetworkTestObject::test<4>()
+	{			
+		// Override with loginuri
+		// override known grid
+		LLSD grid;
+		gCmdLineGridChoice = "Aditi";
+		gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi";		
+		LLGridManager::getInstance()->initialize("grid_test.xml");		
+		std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();		
+		ensure_equals("Override known grid login uri: No grids are added", 
+					  known_grids.size(), 23);
+		LLGridManager::getInstance()->getGridInfo(grid);
+		ensure("Override known grid login uri: login uri is an array",
+			   grid[GRID_LOGIN_URI_VALUE].isArray());
+		ensure_equals("Override known grid login uri: Command line grid login uri is set",
 					  grid[GRID_LOGIN_URI_VALUE][0].asString(), 
 					  std::string("https://my.login.uri/cgi-bin/login.cgi"));
+		ensure_equals("Override known grid login uri: helper uri is not changed",
+					  grid[GRID_HELPER_URI_VALUE].asString(), 
+					  std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/"));
+		ensure_equals("Override known grid login uri: login page is not set",
+					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
+					  std::string("http://secondlife.com/app/login/"));		
 		
-		// add a helperuri
-		gCmdLineHelperURI = "myhelperuri";
-		LLGridManager::getInstance()->initialize("grid_test.xml");
-		grid = LLGridManager::getInstance()->getGridInfo("mycustomgridchoice");		
-		ensure_equals("Validate command line helper uri", 
-					  grid[GRID_HELPER_URI_VALUE].asString(), std::string("myhelperuri"));		
+		// Override with loginuri
+		// override custom grid
+		gCmdLineGridChoice = "mycustomgridchoice";
+		gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi";		
+		LLGridManager::getInstance()->initialize("grid_test.xml");		
+		known_grids = LLGridManager::getInstance()->getKnownGrids();
+		LLGridManager::getInstance()->getGridInfo(grid);
+		ensure_equals("Override custom grid login uri: Grid is added", 
+					  known_grids.size(), 24);		
+		ensure("Override custom grid login uri: login uri is an array",
+			   grid[GRID_LOGIN_URI_VALUE].isArray());
+		ensure_equals("Override custom grid login uri: login uri is set",
+					  grid[GRID_LOGIN_URI_VALUE][0].asString(), 
+					  std::string("https://my.login.uri/cgi-bin/login.cgi"));
+		ensure_equals("Override custom grid login uri: Helper uri is not set",
+					  grid[GRID_HELPER_URI_VALUE].asString(), 
+					  std::string("https://mycustomgridchoice/helpers/"));
+		ensure_equals("Override custom grid login uri: Login page is not set",
+					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
+					  std::string("http://mycustomgridchoice/app/login/"));
+	}
+	
+	// validate override of helper uri with cmd line
+	template<> template<>
+	void viewerNetworkTestObject::test<5>()
+	{	
+		// Override with helperuri
+		// override known grid
+		LLSD grid;
+		gCmdLineGridChoice = "Aditi";
+		gCmdLineLoginURI = "";
+		gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers";		
+		LLGridManager::getInstance()->initialize("grid_test.xml");		
+		std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();		
+		ensure_equals("Override known grid helper uri: No grids are added", 
+					  known_grids.size(), 23);
+		LLGridManager::getInstance()->getGridInfo(grid);
+		ensure("Override known known helper uri: login uri is an array",
+			   grid[GRID_LOGIN_URI_VALUE].isArray());
+		ensure_equals("Override known grid helper uri: login uri is not changed",
+					  grid[GRID_LOGIN_URI_VALUE][0].asString(), 
+					  std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi"));
+		ensure_equals("Override known grid helper uri: helper uri is changed",
+					  grid[GRID_HELPER_URI_VALUE].asString(), 
+					  std::string("https://my.helper.uri/mycustomhelpers"));
+		ensure_equals("Override known grid helper uri: login page is not changed",
+					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
+					  std::string("http://secondlife.com/app/login/"));		
+		
+		// Override with helperuri
+		// override custom grid
+		gCmdLineGridChoice = "mycustomgridchoice";
+		gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers";		
+		LLGridManager::getInstance()->initialize("grid_test.xml");	
+		known_grids = LLGridManager::getInstance()->getKnownGrids();
+		ensure_equals("Override custom grid helper uri: grids is added", 
+					  known_grids.size(), 24);
+		LLGridManager::getInstance()->getGridInfo(grid);
+		ensure("Override custom helper uri: login uri is an array",
+			   grid[GRID_LOGIN_URI_VALUE].isArray());
+		ensure_equals("Override custom grid helper uri: login uri is not changed",
+					  grid[GRID_LOGIN_URI_VALUE][0].asString(), 
+					  std::string("https://mycustomgridchoice/cgi-bin/login.cgi"));
+		ensure_equals("Override custom grid helper uri: helper uri is changed",
+					  grid[GRID_HELPER_URI_VALUE].asString(), 
+					  std::string("https://my.helper.uri/mycustomhelpers"));
+		ensure_equals("Override custom grid helper uri: login page is not changed",
+					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
+					  std::string("http://mycustomgridchoice/app/login/"));
+	}
+	
+	// validate overriding of login page via cmd line
+	template<> template<>
+	void viewerNetworkTestObject::test<6>()
+	{	
+		// Override with login page
+		// override known grid
+		LLSD grid;
+		gCmdLineGridChoice = "Aditi";
+		gCmdLineHelperURI = "";
+		gLoginPage = "myloginpage";		
+		LLGridManager::getInstance()->initialize("grid_test.xml");		
+		std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();				
+		ensure_equals("Override known grid login page: No grids are added", 
+					  known_grids.size(), 23);
+		LLGridManager::getInstance()->getGridInfo(grid);
+		ensure("Override known grid login page: Command line grid login uri is an array",
+			   grid[GRID_LOGIN_URI_VALUE].isArray());
+		ensure_equals("Override known grid login page: login uri is not changed",
+					  grid[GRID_LOGIN_URI_VALUE][0].asString(), 
+					  std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi"));
+		ensure_equals("Override known grid login page: helper uri is not changed",
+					  grid[GRID_HELPER_URI_VALUE].asString(), 
+					  std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/"));
+		ensure_equals("Override known grid login page: login page is changed",
+					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
+					  std::string("myloginpage"));		
 		
-		// add a login page
+		// Override with login page
+		// override custom grid
+		gCmdLineGridChoice = "mycustomgridchoice";
 		gLoginPage = "myloginpage";
-		LLGridManager::getInstance()->initialize("grid_test.xml");
-		grid = LLGridManager::getInstance()->getGridInfo("mycustomgridchoice");		
-		ensure_equals("Validate command line helper uri", 
-					  grid[GRID_LOGIN_PAGE_VALUE].asString(), std::string("myloginpage"));			
+		LLGridManager::getInstance()->initialize("grid_test.xml");		
+		known_grids = LLGridManager::getInstance()->getKnownGrids();
+		ensure_equals("Override custom grid login page: grids are added", 
+					  known_grids.size(), 24);
+		LLGridManager::getInstance()->getGridInfo(grid);
+		ensure("Override custom grid login page: Command line grid login uri is an array",
+			   grid[GRID_LOGIN_URI_VALUE].isArray());
+		ensure_equals("Override custom grid login page: login uri is not changed",
+					  grid[GRID_LOGIN_URI_VALUE][0].asString(), 
+					  std::string("https://mycustomgridchoice/cgi-bin/login.cgi"));
+		ensure_equals("Override custom grid login page: helper uri is not changed",
+					  grid[GRID_HELPER_URI_VALUE].asString(), 
+					  std::string("https://mycustomgridchoice/helpers/"));
+		ensure_equals("Override custom grid login page: login page is changed",
+					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
+					  std::string("myloginpage"));	
+		
 	}
 	
 	// validate grid selection
 	template<> template<>
-	void viewerNetworkTestObject::test<4>()
+	void viewerNetworkTestObject::test<7>()
 	{	
 		LLSD loginURI = LLSD::emptyArray();
 		LLSD grid = LLSD::emptyMap();
@@ -340,20 +466,20 @@ namespace tut
 		ensure("Is myaddedgrid a production grid", !LLGridManager::getInstance()->isInProductionGrid());
 		
 		LLGridManager::getInstance()->setFavorite();
-		grid = LLGridManager::getInstance()->getGridInfo("myaddedgrid");
+		LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid);
 		ensure("setting favorite", grid.has(GRID_IS_FAVORITE_VALUE));
 	}
 	
 	// name based grid population
 	template<> template<>
-	void viewerNetworkTestObject::test<5>()
+	void viewerNetworkTestObject::test<8>()
 	{
 		LLGridManager::getInstance()->initialize("grid_test.xml");
 		LLSD grid = LLSD::emptyMap();
 		// adding a grid with simply a name will populate the values.
 		grid[GRID_VALUE] = "myaddedgrid";
 		LLGridManager::getInstance()->addGrid(grid);
-		grid = LLGridManager::getInstance()->getGridInfo("myaddedgrid");
+		LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid);
 		
 		ensure_equals("name based grid has name value", 
 					  grid[GRID_VALUE].asString(),
@@ -386,7 +512,7 @@ namespace tut
 	
 	// persistence of the grid list with an empty gridfile.
 	template<> template<>
-	void viewerNetworkTestObject::test<6>()
+	void viewerNetworkTestObject::test<9>()
 	{
 		// try with initial grid list without a grid file,
 		// without setting the grid to a saveable favorite.
@@ -420,7 +546,7 @@ namespace tut
 	
 	// persistence of the grid file with existing gridfile
 	template<> template<>
-	void viewerNetworkTestObject::test<7>()
+	void viewerNetworkTestObject::test<10>()
 	{
 		
 		llofstream gridfile("grid_test.xml");