diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index 44291eb71165205be1523a02afac9f96829178ca..2d5f964deb2fa62efe9ee671ae85175e1e0ae568 100755
--- a/indra/llcommon/lleventcoro.cpp
+++ b/indra/llcommon/lleventcoro.cpp
@@ -229,13 +229,26 @@ LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requ
     return value;
 }
 
-LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& pump, F32 timeoutin, const LLSD &timeoutResult)
+LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, 
+        F32 timeoutin, const LLSD &timeoutResult)
 {
-    LLEventTimeout timeoutPump(pump);
+    /**
+     * The timeout pump is attached upstream of of the waiting pump and will 
+     * pass the timeout event through it.  We CAN NOT attach downstream since
+     * doing so will cause the suspendPump to fire any waiting events immediately 
+     * and they will be lost.  This becomes especially problematic with the 
+     * LLEventTimeout(pump) constructor which will also attempt to fire those
+     * events using the virtual listen_impl method in the not yet fully constructed
+     * timeoutPump.
+     */
+    LLEventTimeout timeoutPump;
+    LLEventPump &suspendPump = suspendPumpOrName.getPump();
+
+    LLTempBoundListener timeoutListener(timeoutPump.listen(suspendPump.getName(), 
+            boost::bind(&LLEventPump::post, &suspendPump, _1)));
 
     timeoutPump.eventAfter(timeoutin, timeoutResult);
-    return llcoro::suspendUntilEventOn(timeoutPump);
-
+    return llcoro::suspendUntilEventOn(suspendPump);
 }
 
 namespace
diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h
index 19c68e1f35ad2b03975fbf4ec2a59dbb099b00c0..87926c692deae5586a83be90ae7fd42642649703 100755
--- a/indra/llcommon/lleventcoro.h
+++ b/indra/llcommon/lleventcoro.h
@@ -147,7 +147,10 @@ LLSD suspendUntilEventOn(const LLEventPumpOrPumpName& pump)
     return postAndSuspend(LLSD(), LLEventPumpOrPumpName(), pump);
 }
 
-LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& pump, F32 timeoutin, const LLSD &timeoutResult);
+/// Suspend the coroutine until an event is fired on the identified pump
+/// or the timeout duration has elapsed.  If the timeout duration 
+/// elapses the specified LLSD is returned.
+LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, F32 timeoutin, const LLSD &timeoutResult);
 
 } // namespace llcoro
 
diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h
index 15bac5fd735c23b4977caf43274f7cc83df3f9fe..66f3c1486950e60bb7c387446f1a3b6aac271421 100755
--- a/indra/llcommon/lleventfilter.h
+++ b/indra/llcommon/lleventfilter.h
@@ -188,7 +188,19 @@ class LL_COMMON_API LLEventTimeoutBase: public LLEventFilter
     Action mAction;
 };
 
-/// Production implementation of LLEventTimoutBase
+/**
+ * Production implementation of LLEventTimoutBase.
+ * 
+ * @NOTE: Caution should be taken when using the LLEventTimeout(LLEventPump &) 
+ * constructor to ensure that the upstream event pump is not an LLEventMaildrop
+ * or any other kind of store and forward pump which may have events outstanding.
+ * Using this constructor will cause the upstream event pump to fire any pending
+ * events and could result in the invocation of a virtual method before the timeout
+ * has been fully constructed. The timeout should instead be connected upstream
+ * from the event pump and attached using the listen method.
+ * See llcoro::suspendUntilEventOnWithTimeout() for an example.
+ */
+ 
 class LL_COMMON_API LLEventTimeout: public LLEventTimeoutBase
 {
 public:
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 6175329a9d0bc778f4471cded0d7193fab5f7da1..ba4fcd766ee594ff2b9c04b2582dc30fa75fb3a5 100755
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -616,6 +616,12 @@ class LL_COMMON_API LLEventStream: public LLEventPump
  * a queue. Subsequent attaching listeners will receive stored events from the queue 
  * until a listener indicates that the event has been handled.  In order to receive 
  * multiple events from a mail drop the listener must disconnect and reconnect.
+ * 
+ * @NOTE: When using an LLEventMailDrop (or LLEventQueue) with a LLEventTimeout or
+ * LLEventFilter attaching the filter downstream using Timeout's constructor will
+ * cause the MailDrop to discharge any of it's stored events. The timeout should 
+ * instead be connected upstream using its listen() method.  
+ * See llcoro::suspendUntilEventOnWithTimeout() for an example.
  */
 class LL_COMMON_API LLEventMailDrop : public LLEventStream
 {
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 4316db115e76df59cbe3f778a15100f83f9439b1..07427e0377d249cfe88f3204215b74fedeb82993 100755
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -900,8 +900,7 @@ bool LLVivoxVoiceClient::loginToVivox()
 {
     LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
 
-    LLSD timeoutResult;
-    timeoutResult["login"] = LLSD::String("timeout");
+    LLSD timeoutResult(LLSDMap("login", "timeout"));
 
     int loginRetryCount(0);
 
@@ -1012,8 +1011,7 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)
     if (wait)
     {
         LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
-        LLSD timeoutResult;
-        timeoutResult["logout"] = LLSD::String("timeout");
+        LLSD timeoutResult(LLSDMap("lougout", "timeout"));
 
         LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
 
@@ -1216,8 +1214,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
     bool added(true);
     bool joined(false);
 
-    LLSD timeoutResult;
-    timeoutResult["session"] = LLSD::String("timeout");
+    LLSD timeoutResult(LLSDMap("session", "timeout"));
 
     // It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4
     // before continuing from this state.  They can happen in either order, and if I don't wait for both, things can get stuck.
@@ -1498,8 +1495,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
     notifyParticipantObservers();
     notifyVoiceFontObservers();
 
-    LLSD timeoutEvent = LLSD::emptyMap();
-    timeoutEvent["timeout"] = LLSD::Boolean(true);
+    LLSD timeoutEvent(LLSDMap("timeout", LLSD::Boolean(true)));
 
     LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
     mIsInChannel = true;
@@ -1651,8 +1647,7 @@ void LLVivoxVoiceClient::recordingAndPlaybackMode()
 
 int LLVivoxVoiceClient::voiceRecordBuffer()
 {
-    LLSD timeoutResult; 
-    timeoutResult["recplay"] = LLSD::String("stop");
+    LLSD timeoutResult(LLSDMap("recplay", "stop")); 
 
     LL_INFOS("Voice") << "Recording voice buffer" << LL_ENDL;
 
@@ -1682,8 +1677,7 @@ int LLVivoxVoiceClient::voiceRecordBuffer()
 
 int LLVivoxVoiceClient::voicePlaybackBuffer()
 {
-    LLSD timeoutResult;
-    timeoutResult["recplay"] = LLSD::String("stop");
+    LLSD timeoutResult(LLSDMap("recplay", "stop"));
 
     LL_INFOS("Voice") << "Playing voice buffer" << LL_ENDL;
 
@@ -2922,11 +2916,9 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
 			session->mErrorStatusString = statusString;
 			if(session == mAudioSession)
 			{
-                LLSD vivoxevent = LLSD::emptyMap();
-
-                vivoxevent["handle"] = LLSD::String(sessionHandle);
-                vivoxevent["session"] = LLSD::String("failed");
-                vivoxevent["reason"] = LLSD::Integer(statusCode);
+                LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+                        ("session", "failed")
+                        ("reason", LLSD::Integer(statusCode)));
 
                 LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
             }
@@ -2943,10 +2935,8 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
 		{
 			setSessionHandle(session, sessionHandle);
 		}
-        LLSD vivoxevent = LLSD::emptyMap();
-
-        vivoxevent["handle"] = LLSD::String(sessionHandle);
-        vivoxevent["session"] = LLSD::String("created");
+        LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+                ("session", "created"));
 
         LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
 	}
@@ -2970,10 +2960,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
 			session->mErrorStatusString = statusString;
 			if(session == mAudioSession)
 			{
-                LLSD vivoxevent = LLSD::emptyMap();
-
-                vivoxevent["handle"] = LLSD::String(sessionHandle);
-                vivoxevent["session"] = LLSD::String("failed");
+                LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+                    ("session", "failed"));
 
                 LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
 			}
@@ -2991,10 +2979,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
 			setSessionHandle(session, sessionHandle);
 		}
 
-        LLSD vivoxevent = LLSD::emptyMap();
-
-        vivoxevent["handle"] = LLSD::String(sessionHandle);
-        vivoxevent["session"] = LLSD::String("added");
+        LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+            ("session", "added"));
 
         LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
 
@@ -3039,9 +3025,7 @@ void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusStrin
 		LL_WARNS("Voice") << "Account.Logout response failure: " << statusString << LL_ENDL;
 		// Should this ever fail?  do we care if it does?
 	}
-    LLSD vivoxevent = LLSD::emptyMap();
-
-    vivoxevent["logout"] = LLSD::Boolean(true);
+    LLSD vivoxevent(LLSDMap("logout", LLSD::Boolean(true)));
 
     LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
 }
@@ -3056,9 +3040,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &
 	
 	mConnected = false;
 	
-    LLSD vivoxevent = LLSD::emptyMap();
-
-    vivoxevent["connector"] = LLSD::Boolean(false);
+    LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
 
     LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
 }
@@ -3166,10 +3148,8 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session)
 	// This is the session we're joining.
 	if(mIsJoiningSession)
 	{
-        LLSD vivoxevent = LLSD::emptyMap();
-
-        vivoxevent["handle"] = LLSD::String(session->mHandle);
-        vivoxevent["session"] = LLSD::String("joined");
+        LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
+                ("session", "joined"));
 
         LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
 
@@ -3312,10 +3292,8 @@ void LLVivoxVoiceClient::leftAudioSession(const sessionStatePtr_t &session)
 {
     if (mAudioSession == session)
     {
-        LLSD vivoxevent = LLSD::emptyMap();
-
-        vivoxevent["handle"] = LLSD::String(session->mHandle);
-        vivoxevent["session"] = LLSD::String("removed");
+        LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
+            ("session", "removed"));
 
         LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
     }
@@ -6170,9 +6148,7 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st
     {
         // *TODO: We seem to get multiple events of this type.  Should figure a way to advance only after
         // receiving the last one.
-        LLSD result = LLSD::emptyMap();
-
-        result["voice_fonts"] = LLSD::Boolean(true);
+        LLSD result(LLSDMap("voice_fonts", LLSD::Boolean(true)));
 
         LLEventPumps::instance().post("vivoxClientPump", result);
     }
@@ -6345,8 +6321,7 @@ void LLVivoxVoiceClient::recordPreviewBuffer()
 
 	mCaptureBufferRecording = true;
 
-    LLSD result;
-    result["recplay"] = "record";
+    LLSD result(LLSDMap("recplay", "record"));
     LLEventPumps::instance().post("vivoxClientPump", result);
 }
 
@@ -6369,8 +6344,7 @@ void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id)
 	mPreviewVoiceFont = effect_id;
 	mCaptureBufferPlaying = true;
 
-    LLSD result;
-    result["recplay"] = "playback";
+    LLSD result(LLSDMap("recplay", "playback"));
     LLEventPumps::instance().post("vivoxClientPump", result);
 }
 
@@ -6379,8 +6353,7 @@ void LLVivoxVoiceClient::stopPreviewBuffer()
 	mCaptureBufferRecording = false;
 	mCaptureBufferPlaying = false;
 
-    LLSD result;
-    result["recplay"] = "quit";
+    LLSD result(LLSDMap("recplay", "quit"));
     LLEventPumps::instance().post("vivoxClientPump", result);
 }