diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp
index 080830a134dbdb864afd7c3e123d23a876217d79..fc2d8d5e2382a3a763269dbf4bf455f623b0ecc7 100755
--- a/indra/llcommon/llevents.cpp
+++ b/indra/llcommon/llevents.cpp
@@ -512,10 +512,11 @@ bool LLEventStream::post(const LLSD& event)
  *****************************************************************************/
 bool LLEventMailDrop::post(const LLSD& event)
 {
-    bool posted = LLEventPump::post(event);
+    bool posted = LLEventStream::post(event);
     
     if (!posted)
-    {
+    {   // if the event was not handled we will save it for later so that it can 
+        // be posted to any future listeners when they attach.
         mEventHistory.push_back(event);
     }
     
@@ -527,15 +528,17 @@ LLBoundListener LLEventMailDrop::listen_impl(const std::string& name,
                                     const NameList& after,
                                     const NameList& before)
 {
-    LLBoundListener bndlistener = LLEventPump::listen_impl(name, listener, after, before);
-    
-    return bndlistener;
-}
-
-//    typedef std::list<LLSD> EventList;
-//    EventList mEventHistory;
+    if (!mEventHistory.empty())
+    {
+        if (listener(mEventHistory.front()))
+        {
+            mEventHistory.pop_front();
+        }
+    }
 
+    return LLEventStream::listen_impl(name, listener, after, before);
 
+}
 
 
 /*****************************************************************************
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index b07db889c0c0bd987f2d5099f9c676d5617b04a5..6175329a9d0bc778f4471cded0d7193fab5f7da1 100755
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -508,7 +508,7 @@ public:
         // at the boost::bind object itself before that happens.
         return LLEventDetail::visit_and_connect(name,
                                                 listener,
-                                                boost::bind(&LLEventPump::listen_impl,
+                                                boost::bind(&LLEventPump::listen_invoke,
                                                             this,
                                                             name,
                                                             _1,
@@ -553,7 +553,16 @@ private:
 
     virtual void reset();
 
+
+
 private:
+    LLBoundListener listen_invoke(const std::string& name, const LLEventListener& listener,
+        const NameList& after,
+        const NameList& before)
+    {
+        return this->listen_impl(name, listener, after, before);
+    }
+
     std::string mName;
 
 protected:
@@ -604,13 +613,14 @@ public:
 /**
  * LLEventMailDrop is a specialization of LLEventStream. Events are posted normally, 
  * however if no listeners return that they have handled the event it is placed in 
- * a list.  Subsequent attaching listeners will recieve stored events until a 
- * listener indicates that the event has been handled.
+ * 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.
  */
-class LL_COMMON_API LLEventMailDrop: public LLEventPump
+class LL_COMMON_API LLEventMailDrop : public LLEventStream
 {
 public:
-    LLEventMailDrop(const std::string& name, bool tweak=false): LLEventPump(name, tweak) {}
+    LLEventMailDrop(const std::string& name, bool tweak = false) : LLEventStream(name, tweak) {}
     virtual ~LLEventMailDrop() {}
     
     /// Post an event to all listeners
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 4c7cd658454109480b0ff1bacea312fb34b91ca0..a27afef052f38be86ae37f1913ceaf7ea35c402a 100755
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -220,7 +220,9 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 	mAvatarNameCacheConnection(),
     mIsInTuningMode(false),
     mIsInChannel(false),
-    mIsJoiningSession(false)
+    mIsJoiningSession(false),
+
+    mVivoxPump("vivoxClientPump")
 {	
 	mSpeakerVolume = scale_speaker_volume(0);
 
@@ -243,6 +245,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 		signal(SIGCHLD, SIG_IGN);
 #endif
 
+
 	// set up state machine
 	setState(stateDisabled);
 	
@@ -806,17 +809,17 @@ void LLVivoxVoiceClient::stateMachine()
 
 	}
 	
-	if (mAudioSessionChanged)
-	{
-		mAudioSessionChanged = false;
-		notifyParticipantObservers();
-		notifyVoiceFontObservers();
-	}
-	else if (mAudioSession && mAudioSession->mParticipantsChanged)
-	{
-		mAudioSession->mParticipantsChanged = false;
-		notifyParticipantObservers();
-	}
+// 	if (mAudioSessionChanged)
+// 	{
+// 		mAudioSessionChanged = false;
+// 		notifyParticipantObservers();
+// 		notifyVoiceFontObservers();
+// 	}
+// 	else if (mAudioSession && mAudioSession->mParticipantsChanged)
+// 	{
+// 		mAudioSession->mParticipantsChanged = false;
+// 		notifyParticipantObservers();
+// 	}
 }
 
 //=========================================================================
@@ -829,6 +832,7 @@ void LLVivoxVoiceClient::stateMachine()
 // 
 void LLVivoxVoiceClient::voiceControlCoro()
 {
+    LLCoros::set_consuming(true);
     startAndConnectSession();
 
     if (mTuningMode)
@@ -1429,6 +1433,15 @@ bool LLVivoxVoiceClient::addAndJoinSession(sessionState *nextSession)
         LL_INFOS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
         if (result.has("session"))
         {
+            if (result.has("handle"))
+            {
+                if (result["handle"] != mAudioSession->mHandle)
+                {
+                    LL_WARNS("Voice") << "Message for session handle \"" << result["handle"] << "\" while waiting for \"" << mAudioSession->mHandle << "\"." << LL_ENDL;
+                    continue;
+                }
+            }
+
             std::string message = result["session"].asString();
             if ((message == "added") || (message == "created"))
                 added = true;
@@ -1447,7 +1460,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(sessionState *nextSession)
 
     if (mSpatialJoiningNum > 100)
     {
-        LL_WARNS() << "There seems to be problem with connecting to a voice channel. Frames to join were " << mSpatialJoiningNum << LL_ENDL;
+        LL_WARNS("Voice") << "There seems to be problem with connecting to a voice channel. Frames to join were " << mSpatialJoiningNum << LL_ENDL;
     }
 
     mSpatialJoiningNum = 0;
@@ -1465,7 +1478,6 @@ bool LLVivoxVoiceClient::addAndJoinSession(sessionState *nextSession)
 
 bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
 {
-    notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
 
     if (mAudioSession)
     {
@@ -1502,6 +1514,15 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
                     LL_INFOS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
                     if (result.has("session"))
                     {
+                        if (result.has("handle"))
+                        {
+                            if (result["handle"] != mAudioSession->mHandle)
+                            {
+                                LL_WARNS("Voice") << "Message for session handle \"" << result["handle"] << "\" while waiting for \"" << mAudioSession->mHandle << "\"." << LL_ENDL;
+                                continue;
+                            }
+                        }
+
                         std::string message = result["session"].asString();
                         if (message == "removed")
                             break;
@@ -1529,6 +1550,8 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
     {
         LL_WARNS("Voice") << "stateSessionTerminated with NULL mAudioSession" << LL_ENDL;
     }
+
+    notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
     setState(stateSessionTerminated);
 
     // Always reset the terminate request flag when we get here.
@@ -1602,6 +1625,9 @@ bool LLVivoxVoiceClient::waitForChannel()
             {
                 runSession(mNextAudioSession);
             }
+
+            if (!mNextAudioSession)
+                llcoro::suspendUntilTimeout(1.0);
         } while (mVoiceEnabled && !mRelogRequested);
 
     } while (mVoiceEnabled && mRelogRequested);
@@ -1624,6 +1650,9 @@ bool LLVivoxVoiceClient::runSession(sessionState *session)
         return false;
     }
 
+    notifyParticipantObservers();
+    notifyVoiceFontObservers();
+
     LLSD timeoutEvent = LLSD::emptyMap();
     timeoutEvent["timeout"] = LLSD::Boolean(true);
 
@@ -1680,6 +1709,15 @@ bool LLVivoxVoiceClient::runSession(sessionState *session)
             LL_INFOS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
         if (result.has("session"))
         {   
+            if (result.has("handle"))
+            {
+                if (result["handle"] != mAudioSession->mHandle)
+                {
+                    LL_WARNS("Voice") << "Message for session handle \"" << result["handle"] << "\" while waiting for \"" << mAudioSession->mHandle << "\"." << LL_ENDL;
+                    continue;
+                }
+            }
+
             std::string message = result["session"];
 
             if (message == "removed")
@@ -1688,6 +1726,12 @@ bool LLVivoxVoiceClient::runSession(sessionState *session)
                 break;
             }
         }
+    
+        if (mAudioSession && mAudioSession->mParticipantsChanged)
+        {
+            mAudioSession->mParticipantsChanged = false;
+            notifyParticipantObservers();
+        }
     }
 
     mIsInChannel = false;
@@ -3038,6 +3082,7 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
 			{
                 LLSD vivoxevent = LLSD::emptyMap();
 
+                vivoxevent["handle"] = LLSD::String(sessionHandle);
                 vivoxevent["session"] = LLSD::String("failed");
 
                 LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
@@ -3057,6 +3102,7 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
 		}
         LLSD vivoxevent = LLSD::emptyMap();
 
+        vivoxevent["handle"] = LLSD::String(sessionHandle);
         vivoxevent["session"] = LLSD::String("created");
 
         LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
@@ -3083,6 +3129,7 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
 			{
                 LLSD vivoxevent = LLSD::emptyMap();
 
+                vivoxevent["handle"] = LLSD::String(sessionHandle);
                 vivoxevent["session"] = LLSD::String("failed");
 
                 LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
@@ -3103,6 +3150,7 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
 
         LLSD vivoxevent = LLSD::emptyMap();
 
+        vivoxevent["handle"] = LLSD::String(sessionHandle);
         vivoxevent["session"] = LLSD::String("added");
 
         LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
@@ -3273,6 +3321,7 @@ void LLVivoxVoiceClient::joinedAudioSession(sessionState *session)
 	{
         LLSD vivoxevent = LLSD::emptyMap();
 
+        vivoxevent["handle"] = LLSD::String(session->mHandle);
         vivoxevent["session"] = LLSD::String("joined");
 
         LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
@@ -3421,6 +3470,7 @@ void LLVivoxVoiceClient::leftAudioSession(
     {
         LLSD vivoxevent = LLSD::emptyMap();
 
+        vivoxevent["handle"] = LLSD::String(session->mHandle);
         vivoxevent["session"] = LLSD::String("removed");
 
         LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 3da24c61f3af617478da8e6251264966f5d0cd12..6cbd5efdcd06eaa426f479c03f665caf8a4282e7 100755
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -937,6 +937,8 @@ private:
     bool    mIsInTuningMode;
     bool    mIsInChannel;
     bool    mIsJoiningSession;
+
+    LLEventMailDrop mVivoxPump;
 };
 
 /**