diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index cc6bddc4dab08f32695dd6ef403c41cbdd1cf249..60d4cfe6d30e1d0919df89d3b0900f6de4559128 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -322,6 +322,7 @@ if (LL_TESTS)
   LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}"
                           "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/setpython.py")
+  LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}")                          
   LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 00757be27744c29f78b80aa72897500d0cff7553..49d99f2cd0fe7f0cf1665115dc83d0d883b98c24 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -114,8 +114,7 @@ class LLSingleton : private boost::noncopyable
 
 		~SingletonInstanceData()
 		{
-			SingletonInstanceData& data = getData();
-			if (data.mInitState != DELETED)
+			if (mInitState != DELETED)
 			{
 				deleteSingleton();
 			}
@@ -130,7 +129,26 @@ class LLSingleton : private boost::noncopyable
 		data.mInitState = DELETED;
 	}
 
-	// Can be used to control when the singleton is deleted.  Not normally needed.
+	/**
+	 * @brief Immediately delete the singleton.
+	 *
+	 * A subsequent call to LLProxy::getInstance() will construct a new
+	 * instance of the class.
+	 *
+	 * LLSingletons are normally destroyed after main() has exited and the C++
+	 * runtime is cleaning up statically-constructed objects. Some classes
+	 * derived from LLSingleton have objects that are part of a runtime system
+	 * that is terminated before main() exits. Calling the destructor of those
+	 * objects after the termination of their respective systems can cause
+	 * crashes and other problems during termination of the project. Using this
+	 * method to destroy the singleton early can prevent these crashes.
+	 *
+	 * An example where this is needed is for a LLSingleton that has an APR
+	 * object as a member that makes APR calls on destruction. The APR system is
+	 * shut down explicitly before main() exits. This causes a crash on exit.
+	 * Using this method before the call to apr_terminate() and NOT calling
+	 * getInstance() again will prevent the crash.
+	 */
 	static void deleteSingleton()
 	{
 		delete getData().mSingletonInstance;
diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..385289aefef69b16997148840929fe7b94963c3f
--- /dev/null
+++ b/indra/llcommon/tests/llsingleton_test.cpp
@@ -0,0 +1,76 @@
+/** 
+ * @file llsingleton_test.cpp
+ * @date 2011-08-11
+ * @brief Unit test for the LLSingleton class
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llsingleton.h"
+#include "../test/lltut.h"
+
+namespace tut
+{
+	struct singleton
+	{
+		// We need a class created with the LLSingleton template to test with.
+		class LLSingletonTest: public LLSingleton<LLSingletonTest>
+		{
+
+		};
+	};
+
+	typedef test_group<singleton> singleton_t;
+	typedef singleton_t::object singleton_object_t;
+	tut::singleton_t tut_singleton("LLSingleton");
+
+	template<> template<>
+	void singleton_object_t::test<1>()
+	{
+
+	}
+	template<> template<>
+	void singleton_object_t::test<2>()
+	{
+		LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+		ensure(singleton_test);
+	}
+	template<> template<>
+	void singleton_object_t::test<3>()
+	{
+		//Construct the instance
+		LLSingletonTest::getInstance();
+		ensure(LLSingletonTest::instanceExists());
+
+		//Delete the instance
+		LLSingletonTest::deleteSingleton();
+		ensure(LLSingletonTest::destroyed());
+		ensure(!LLSingletonTest::instanceExists());
+
+		//Construct it again.
+		LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+		ensure(singleton_test);
+		ensure(LLSingletonTest::instanceExists());
+	}
+}
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index a3de178d78fe9a79240bfe148f30b5200149437e..14e169c6b1011a351d582a0ae8e9b131e2daaf19 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -499,7 +499,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
 	
 	//don't verify host name so urls with scrubbed host names will work (improves DNS performance)
 	setopt(CURLOPT_SSL_VERIFYHOST, 0);
-	setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
+	setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));
 
 	setoptString(CURLOPT_URL, url);
 
@@ -1213,3 +1213,13 @@ void LLCurl::cleanupClass()
 }
 
 const unsigned int LLCurl::MAX_REDIRECTS = 5;
+
+// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
+void LLCurlFF::check_easy_code(CURLcode code)
+{
+	check_curl_code(code);
+}
+void LLCurlFF::check_multi_code(CURLMcode code)
+{
+	check_curl_multi_code(code);
+}
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 5ab4dc35b91e3ea65bf27166a95e22756ba199f8..213b281e72de5f3602ecd83d01cb8d96b67ce88c 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -371,7 +371,11 @@ class LLCurlEasyRequest
 	bool mResultReturned;
 };
 
-void check_curl_code(CURLcode code);
-void check_curl_multi_code(CURLMcode code);
+// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
+namespace LLCurlFF
+{
+	void check_easy_code(CURLcode code);
+	void check_multi_code(CURLMcode code);
+}
 
 #endif // LL_LLCURL_H
diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp
index 7628984de4cc0c53b90c808b1c01b1935b6de5ea..fc6e9c519302d9da1790c21d77daf6cf8f99f2e6 100644
--- a/indra/llmessage/llpacketring.cpp
+++ b/indra/llmessage/llpacketring.cpp
@@ -228,13 +228,13 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
 		if (LLProxy::isSOCKSProxyEnabled())
 		{
 			U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
-			packet_size = receive_packet(socket, reinterpret_cast<char *>(buffer));
+			packet_size = receive_packet(socket, static_cast<char*>(static_cast<void*>(buffer)));
 			
 			if (packet_size > SOCKS_HEADER_SIZE)
 			{
 				// *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
 				memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE);
-				proxywrap_t * header = reinterpret_cast<proxywrap_t *>(buffer);
+				proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer));
 				mLastSender.setAddress(header->addr);
 				mLastSender.setPort(ntohs(header->port));
 
@@ -353,14 +353,20 @@ BOOL LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 bu
 		return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
 	}
 
-	proxywrap_t *socks_header = reinterpret_cast<proxywrap_t *>(&mProxyWrappedSendBuffer);
+	char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
+
+	proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer));
 	socks_header->rsv   = 0;
 	socks_header->addr  = host.getAddress();
 	socks_header->port  = htons(host.getPort());
 	socks_header->atype = ADDRESS_IPV4;
 	socks_header->frag  = 0;
 
-	memcpy(mProxyWrappedSendBuffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
+	memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
 
-	return send_packet(h_socket, (const char*) mProxyWrappedSendBuffer, buf_size + 10, LLProxy::getInstance()->getUDPProxy().getAddress(), LLProxy::getInstance()->getUDPProxy().getPort());
+	return send_packet(	h_socket,
+						headered_send_buffer,
+						buf_size + SOCKS_HEADER_SIZE,
+						LLProxy::getInstance()->getUDPProxy().getAddress(),
+						LLProxy::getInstance()->getUDPProxy().getPort());
 }
diff --git a/indra/llmessage/llpacketring.h b/indra/llmessage/llpacketring.h
index 7edcc834db83338ec72be7523a3607cb0e582a51..b214271e782adde01e3c51590ecf0e29ef639be3 100644
--- a/indra/llmessage/llpacketring.h
+++ b/indra/llmessage/llpacketring.h
@@ -83,9 +83,6 @@ class LLPacketRing
 	LLHost mLastSender;
 	LLHost mLastReceivingIF;
 
-
-	U8 mProxyWrappedSendBuffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
-
 private:
 	BOOL sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
 };
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 19f1fc6545a2b26b16ab3ea4725933e21ac0c097..4a7d326c0e6eae90dfe6e7cb3b6fe0358c075f20 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -43,7 +43,7 @@
 bool LLProxy::sUDPProxyEnabled = false;
 
 // Some helpful TCP static functions.
-static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
+static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
 static LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a given host
 static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel
 
@@ -63,14 +63,13 @@ LLProxy::LLProxy():
 LLProxy::~LLProxy()
 {
 	stopSOCKSProxy();
-	sUDPProxyEnabled  = false;
-	mHTTPProxyEnabled = false;
+	disableHTTPProxy();
 }
 
 /**
  * @brief Open the SOCKS 5 TCP control channel.
  *
- * Perform a SOCKS 5 authentication and UDP association to the proxy server.
+ * Perform a SOCKS 5 authentication and UDP association with the proxy server.
  *
  * @param proxy The SOCKS 5 server to connect to.
  * @return SOCKS_OK if successful, otherwise a socks error code from llproxy.h.
@@ -83,11 +82,15 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 	socks_auth_request_t  socks_auth_request;
 	socks_auth_response_t socks_auth_response;
 
-	socks_auth_request.version     = SOCKS_VERSION;       // SOCKS version 5
-	socks_auth_request.num_methods = 1;                   // Sending 1 method.
-	socks_auth_request.methods     = getSelectedAuthMethod(); // Send only the selected method.
+	socks_auth_request.version		= SOCKS_VERSION;				// SOCKS version 5
+	socks_auth_request.num_methods	= 1;							// Sending 1 method.
+	socks_auth_request.methods		= getSelectedAuthMethod();		// Send only the selected method.
 
-	result = tcp_handshake(mProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request), (char*)&socks_auth_response, sizeof(socks_auth_response));
+	result = tcp_blocking_handshake(mProxyControlChannel,
+									static_cast<char*>(static_cast<void*>(&socks_auth_request)),
+									sizeof(socks_auth_request),
+									static_cast<char*>(static_cast<void*>(&socks_auth_response)),
+									sizeof(socks_auth_response));
 	if (result != APR_SUCCESS)
 	{
 		LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL;
@@ -97,12 +100,12 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 
 	if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE)
 	{
-		LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods" << LL_ENDL;
+		LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods." << LL_ENDL;
 		stopSOCKSProxy();
 		return SOCKS_NOT_ACCEPTABLE;
 	}
 
-	// SOCKS 5 USERNAME/PASSWORD authentication
+	/* SOCKS 5 USERNAME/PASSWORD authentication */
 	if (socks_auth_response.method == METHOD_PASSWORD)
 	{
 		// The server has requested a username/password combination
@@ -114,11 +117,15 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 		password_auth[1] = socks_username.size();
 		memcpy(&password_auth[2], socks_username.c_str(), socks_username.size());
 		password_auth[socks_username.size() + 2] = socks_password.size();
-		memcpy(&password_auth[socks_username.size()+3], socks_password.c_str(), socks_password.size());
+		memcpy(&password_auth[socks_username.size() + 3], socks_password.c_str(), socks_password.size());
 
 		authmethod_password_reply_t password_reply;
 
-		result = tcp_handshake(mProxyControlChannel, password_auth, request_size, (char*)&password_reply, sizeof(password_reply));
+		result = tcp_blocking_handshake(mProxyControlChannel,
+										password_auth,
+										request_size,
+										static_cast<char*>(static_cast<void*>(&password_reply)),
+										sizeof(password_reply));
 		delete[] password_auth;
 
 		if (result != APR_SUCCESS)
@@ -150,7 +157,11 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 	// "If the client is not in possession of the information at the time of the UDP ASSOCIATE,
 	//  the client MUST use a port number and address of all zeros. RFC 1928"
 
-	result = tcp_handshake(mProxyControlChannel, (char*)&connect_request, sizeof(connect_request), (char*)&connect_reply, sizeof(connect_reply));
+	result = tcp_blocking_handshake(mProxyControlChannel,
+									static_cast<char*>(static_cast<void*>(&connect_request)),
+									sizeof(connect_request),
+									static_cast<char*>(static_cast<void*>(&connect_reply)),
+									sizeof(connect_reply));
 	if (result != APR_SUCCESS)
 	{
 		LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL;
@@ -169,6 +180,7 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 	mUDPProxy.setAddress(proxy.getAddress());
 	// The connection was successful. We now have the UDP port to send requests that need forwarding to.
 	LL_INFOS("Proxy") << "SOCKS 5 UDP proxy connected on " << mUDPProxy << LL_ENDL;
+
 	return SOCKS_OK;
 }
 
@@ -176,7 +188,8 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
  * @brief Initiates a SOCKS 5 proxy session.
  *
  * Performs basic checks on host to verify that it is a valid address. Opens the control channel
- * and then negotiates the proxy connection with the server.
+ * and then negotiates the proxy connection with the server. Closes any existing SOCKS
+ * connection before proceeding. Also disables an HTTP proxy if it is using SOCKS as the proxy.
  *
  *
  * @param host Socks server to connect to.
@@ -184,43 +197,37 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
  */
 S32 LLProxy::startSOCKSProxy(LLHost host)
 {
-	S32 status = SOCKS_OK;
-
 	if (host.isOk())
 	{
 		mTCPProxy = host;
 	}
 	else
 	{
-		status = SOCKS_INVALID_HOST;
+		return SOCKS_INVALID_HOST;
 	}
 
-	if (mProxyControlChannel && status == SOCKS_OK)
-	{
-		tcp_close_channel(&mProxyControlChannel);
-	}
+	// Close any running SOCKS connection.
+	stopSOCKSProxy();
 
-	if (status == SOCKS_OK)
+	mProxyControlChannel = tcp_open_channel(mTCPProxy);
+	if (!mProxyControlChannel)
 	{
-		mProxyControlChannel = tcp_open_channel(mTCPProxy);
-		if (!mProxyControlChannel)
-		{
-			status = SOCKS_HOST_CONNECT_FAILED;
-		}
+		return SOCKS_HOST_CONNECT_FAILED;
 	}
 
-	if (status == SOCKS_OK)
-	{
-		status = proxyHandshake(mTCPProxy);
-	}
-	if (status == SOCKS_OK)
+	S32 status = proxyHandshake(mTCPProxy);
+
+	if (status != SOCKS_OK)
 	{
-		sUDPProxyEnabled = true;
+		// Shut down the proxy if any of the above steps failed.
+		stopSOCKSProxy();
 	}
 	else
 	{
-		stopSOCKSProxy();
+		// Connection was successful.
+		sUDPProxyEnabled = true;
 	}
+
 	return status;
 }
 
@@ -241,7 +248,7 @@ void LLProxy::stopSOCKSProxy()
 
 	if (LLPROXY_SOCKS == getHTTPProxyType())
 	{
-		void disableHTTPProxy();
+		disableHTTPProxy();
 	}
 
 	if (mProxyControlChannel)
@@ -349,16 +356,6 @@ void LLProxy::disableHTTPProxy()
 	mHTTPProxyEnabled = false;
 }
 
-/**
- * @brief Get the HTTP proxy address and port
- */
-//
-LLHost LLProxy::getHTTPProxy() const
-{
-	LLMutexLock lock(&mProxyMutex);
-	return mHTTPProxy;
-}
-
 /**
  * @brief Get the currently selected HTTP proxy type
  */
@@ -440,21 +437,21 @@ void LLProxy::applyProxySettings(CURL* handle)
 		// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
 		if (mHTTPProxyEnabled)
 		{
-			check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
-			check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
+			LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
+			LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
 
 			if (mProxyType == LLPROXY_SOCKS)
 			{
-				check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
+				LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
 				if (mAuthMethodSelected == METHOD_PASSWORD)
 				{
 					std::string auth_string = mSocksUsername + ":" + mSocksPassword;
-					check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
+					LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
 				}
 			}
 			else
 			{
-				check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
+				LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
 			}
 		}
 	}
@@ -473,7 +470,7 @@ void LLProxy::applyProxySettings(CURL* handle)
  * @param maxinlen		Maximum possible length of received data.  Short reads are allowed.
  * @return 				Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received.
  */
-static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
+static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
 {
 	apr_socket_t* apr_socket = handle->getSocket();
 	apr_status_t rv = APR_SUCCESS;
@@ -522,7 +519,6 @@ static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outl
  *
  * Checks for a successful connection, and makes sure the connection is closed if it fails.
  *
- * @param pool		APR pool to pass into the LLSocket.
  * @param host		The host to open the connection to.
  * @return			The created socket.  Will evaluate as NULL if the connection is unsuccessful.
  */
@@ -541,7 +537,7 @@ static LLSocket::ptr_t tcp_open_channel(LLHost host)
 /**
  * @brief Close the socket.
  *
- * @param handle_ptr A pointer-to-pointer to avoid increasing the use count.
+ * @param handle_ptr The handle of the socket being closed. A pointer-to-pointer to avoid increasing the use count.
  */
 static void tcp_close_channel(LLSocket::ptr_t* handle_ptr)
 {
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index 621debb61db2a2f80b1597197d09d0108bd74dcc..a9193705404ace5c51168c261d5c9a35bb951f5a 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -36,7 +36,6 @@
 #include <string>
 
 // SOCKS error codes returned from the StartProxy method
-
 #define SOCKS_OK 0
 #define SOCKS_CONNECT_ERROR (-1)
 #define SOCKS_NOT_PERMITTED (-2)
@@ -46,7 +45,6 @@
 #define SOCKS_HOST_CONNECT_FAILED (-6)
 #define SOCKS_INVALID_HOST (-7)
 
-
 #ifndef MAXHOSTNAMELEN
 #define	MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */
 #endif
@@ -225,62 +223,71 @@ class LLProxy: public LLSingleton<LLProxy>
 {
 	LOG_CLASS(LLProxy);
 public:
-	// METHODS THAT DO NOT LOCK mProxyMutex!
-
+	/*###########################################################################################
+	METHODS THAT DO NOT LOCK mProxyMutex!
+	###########################################################################################*/
+	// Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only.
 	LLProxy();
 
-	// static check for enabled status for UDP packets
+	// Static check for enabled status for UDP packets. Call from main thread only.
 	static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
 
-	// check for enabled status for HTTP packets
-	// mHTTPProxyEnabled is atomic, so no locking is required for thread safety.
-	bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; }
-
-	// Get the UDP proxy address and port
+	// Get the UDP proxy address and port. Call from main thread only.
 	LLHost getUDPProxy() const { return mUDPProxy; }
 
-	// Get the SOCKS 5 TCP control channel address and port
-	LLHost getTCPProxy() const { return mTCPProxy; }
+	/*###########################################################################################
+	END OF NON-LOCKING METHODS
+	###########################################################################################*/
 
-	// END OF NON-LOCKING METHODS
+	/*###########################################################################################
+	METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+	###########################################################################################*/
+	// Destructor, closes open connections. Do not call directly, use cleanupClass().
+	~LLProxy();
 
-	// METHODS THAT DO LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+	// Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be
+	// destroyed before the call to apr_terminate. Call from main thread only.
+	static void cleanupClass();
 
-	~LLProxy();
+	// Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
+	// Safe to call from any thread.
+	void applyProxySettings(CURL* handle);
+	void applyProxySettings(LLCurl::Easy* handle);
+	void applyProxySettings(LLCurlEasyRequest* handle);
 
-	// Start a connection to the SOCKS 5 proxy
+	// Start a connection to the SOCKS 5 proxy. Call from main thread only.
 	S32 startSOCKSProxy(LLHost host);
 
-	// Disconnect and clean up any connection to the SOCKS 5 proxy
+	// Disconnect and clean up any connection to the SOCKS 5 proxy. Call from main thread only.
 	void stopSOCKSProxy();
 
-	// Delete LLProxy singleton, destroying the APR pool used by the control channel.
-	static void cleanupClass();
-
-	// Set up to use Password auth when connecting to the SOCKS proxy
+	// Use Password auth when connecting to the SOCKS proxy. Call from main thread only.
 	bool setAuthPassword(const std::string &username, const std::string &password);
 
-	// Set up to use No Auth when connecting to the SOCKS proxy
+	// Disable authentication when connecting to the SOCKS proxy. Call from main thread only.
 	void setAuthNone();
 
-	// Get the currently selected auth method.
-	LLSocks5AuthType getSelectedAuthMethod() const;
-
-	// Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy
-	// as specified in type
+	// Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy.
+	// as specified in type. Call from main thread only.
 	bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type);
 	bool enableHTTPProxy();
 
-	// Stop proxying HTTP packets
+	// Stop proxying HTTP packets. Call from main thread only.
 	void disableHTTPProxy();
 
-	// Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
-	void applyProxySettings(CURL* handle);
-	void applyProxySettings(LLCurl::Easy* handle);
-	void applyProxySettings(LLCurlEasyRequest* handle);
+	/*###########################################################################################
+	END OF LOCKING METHODS
+	###########################################################################################*/
+private:
+	/*###########################################################################################
+	METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+	###########################################################################################*/
 
-	// Get the HTTP proxy address and port
-	LLHost getHTTPProxy() const;
+	// Perform a SOCKS 5 authentication and UDP association with the proxy server.
+	S32 proxyHandshake(LLHost proxy);
+
+	// Get the currently selected auth method.
+	LLSocks5AuthType getSelectedAuthMethod() const;
 
 	// Get the currently selected HTTP proxy type
 	LLHttpProxyType getHTTPProxyType() const;
@@ -288,21 +295,21 @@ class LLProxy: public LLSingleton<LLProxy>
 	std::string getSocksPwd() const;
 	std::string getSocksUser() const;
 
-	// END OF LOCKING METHODS
-private:
-	// Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort
-	S32 proxyHandshake(LLHost proxy);
+	/*###########################################################################################
+	END OF LOCKING METHODS
+	###########################################################################################*/
 
 private:
-	// Is the HTTP proxy enabled?
-	// Safe to read in any thread, do not write directly,
-	// use enableHTTPProxy() and disableHTTPProxy() instead.
+	// Is the HTTP proxy enabled? Safe to read in any thread, but do not write directly.
+	// Instead use enableHTTPProxy() and disableHTTPProxy() instead.
 	mutable LLAtomic32<bool> mHTTPProxyEnabled;
 
-	// Mutex to protect shared members in non-main thread calls to applyProxySettings()
+	// Mutex to protect shared members in non-main thread calls to applyProxySettings().
 	mutable LLMutex mProxyMutex;
 
-	// MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE!
+	/*###########################################################################################
+	MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE!
+	###########################################################################################*/
 
 	// Is the UDP proxy enabled?
 	static bool sUDPProxyEnabled;
@@ -315,9 +322,13 @@ class LLProxy: public LLSingleton<LLProxy>
 	// socket handle to proxy TCP control channel
 	LLSocket::ptr_t mProxyControlChannel;
 
-	// END OF UNSHARED MEMBERS
+	/*###########################################################################################
+	END OF UNSHARED MEMBERS
+	###########################################################################################*/
 
-	// MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex!
+	/*###########################################################################################
+	MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex!
+	###########################################################################################*/
 
 	// HTTP proxy address and port
 	LLHost mHTTPProxy;
@@ -325,7 +336,7 @@ class LLProxy: public LLSingleton<LLProxy>
 	// Currently selected HTTP proxy type. Can be web or socks.
 	LLHttpProxyType mProxyType;
 
-	// SOCKS 5 auth method selected
+	// SOCKS 5 selected authentication method.
 	LLSocks5AuthType mAuthMethodSelected;
 
 	// SOCKS 5 username
@@ -333,7 +344,9 @@ class LLProxy: public LLSingleton<LLProxy>
 	// SOCKS 5 password
 	std::string mSocksPassword;
 
-	// END OF SHARED MEMBERS
+	/*###########################################################################################
+	END OF SHARED MEMBERS
+	###########################################################################################*/
 };
 
 #endif