diff --git a/Aurora/Aurora.csproj b/Aurora/Aurora.csproj
index a6be19b..b46e96e 100644
--- a/Aurora/Aurora.csproj
+++ b/Aurora/Aurora.csproj
@@ -93,5 +93,7 @@
              Include="Proto\party.proto"/>
         
+        
     
 
\ No newline at end of file
diff --git a/Aurora/Design/Components/MemberList/MemberList.xaml.cs b/Aurora/Design/Components/MemberList/MemberList.xaml.cs
index 3294e5b..aed88b8 100644
--- a/Aurora/Design/Components/MemberList/MemberList.xaml.cs
+++ b/Aurora/Design/Components/MemberList/MemberList.xaml.cs
@@ -2,7 +2,7 @@
 using System.Collections.ObjectModel;
 using System.Collections.Specialized;
 using Xamarin.Forms;
-using Aurora.Proto;
+using Aurora.Proto.Party;
 
 namespace Aurora.Design.Components.MemberList
 {
diff --git a/Aurora/Design/Views/Party/PartyViewModel.cs b/Aurora/Design/Views/Party/PartyViewModel.cs
index e70f6e4..17cd9ce 100644
--- a/Aurora/Design/Views/Party/PartyViewModel.cs
+++ b/Aurora/Design/Views/Party/PartyViewModel.cs
@@ -1,7 +1,7 @@
 using System;
 using System.Collections.ObjectModel;
 using Aurora.Executors;
-using Aurora.Proto;
+using Aurora.Proto.Party;
 using Xamarin.Forms;
 
 namespace Aurora.Design.Views.Party
@@ -32,6 +32,15 @@ namespace Aurora.Design.Views.Party
 
             State(PartyState.SelectingHost);
         }
+
+        ~PartyViewModel()
+        {
+            if (_executor != null)
+            {
+                _executor.Close();
+            }
+        }
+
         #region Properties
 
         public ObservableCollection Members
diff --git a/Aurora/Executors/BaseExecutor.cs b/Aurora/Executors/BaseExecutor.cs
index 6033039..f3ed4b8 100644
--- a/Aurora/Executors/BaseExecutor.cs
+++ b/Aurora/Executors/BaseExecutor.cs
@@ -2,8 +2,7 @@ using System;
 using System.Reflection;
 using System.Linq;
 using System.Collections.ObjectModel;
-using Aurora.Proto;
-
+using Aurora.Proto.Party;
 namespace Aurora.Executors
 {
     public abstract class BaseExecutor
diff --git a/Aurora/Executors/ClientExecutor.cs b/Aurora/Executors/ClientExecutor.cs
index 60ce8e6..6f8aeff 100644
--- a/Aurora/Executors/ClientExecutor.cs
+++ b/Aurora/Executors/ClientExecutor.cs
@@ -1,8 +1,13 @@
 using System;
 using System.Collections.ObjectModel;
+using System.Threading.Tasks;
+using System.Threading;
 using Grpc.Core;
-using Aurora.Proto;
-using Aurora.Models;
+using wellKnown = Google.Protobuf.WellKnownTypes;
+using Aurora.Proto.General;
+using Aurora.Proto.Party;
+using Aurora.Proto.Playback;
+using Aurora.Proto.Events;
 using Aurora.Services;
 namespace Aurora.Executors
 {
@@ -11,6 +16,8 @@ namespace Aurora.Executors
         private Channel _channel;
         private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
         private RemotePlaybackService.RemotePlaybackServiceClient _remotePlaybackClient;
+        private RemoteEventService.RemoteEventServiceClient _remoteEventsClient;
+        private Task _eventsTask;
 
         private ObservableCollection _partyMembers;
 
@@ -27,16 +34,28 @@ namespace Aurora.Executors
 
         #endregion Properties
 
+        /// 
+        /// Initiates the connection to a party.
+        /// 
+        /// The hostname of the gRPC server
         public override void Connect(string hostname)
         {
             _channel = new Channel(string.Format("{0}:{1}", hostname, SettingsService.Instance.DefaultPort), ChannelCredentials.Insecure);
 
             _remotePartyClient = new RemotePartyService.RemotePartyServiceClient(_channel);
             _remotePlaybackClient = new RemotePlaybackService.RemotePlaybackServiceClient(_channel);
+            _remoteEventsClient = new RemoteEventService.RemoteEventServiceClient(_channel);
+
+            //Assign but don't start task
+            _eventsTask = new Task(GetEvents);
 
             JoinParty();
         }
 
+        /// 
+        /// Shutdown Connections
+        /// 
+        /// 
         public override async void Close()
         {
             await _channel.ShutdownAsync();
@@ -69,6 +88,28 @@ namespace Aurora.Executors
                 UserName = SettingsService.Instance.Username,
             });
 
+            RefreshMembers();
+
+            //Subscribe to events
+            SubscribeRequest req = new SubscribeRequest();
+            req.EventTypes.Add(EventType.PartyMemberJoined);
+            req.EventTypes.Add(EventType.PartyMemberLeft);
+            try
+            {
+                _remoteEventsClient.SubscribeToEvents(req);
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine("Error subscribing to events: " + ex.Message);
+            }
+
+
+            _eventsTask.Start();
+
+        }
+
+        private void RefreshMembers()
+        {
             MembersResponse resposne = _remotePartyClient.GetPartyMembers(new Empty());
             //Add members
             foreach (PartyMember member in resposne.Members)
@@ -85,5 +126,36 @@ namespace Aurora.Executors
                 }
             }
         }
+
+        private async void GetEvents()
+        {
+
+            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
+            using (AsyncServerStreamingCall eventStream = _remoteEventsClient.GetEvents(new Empty()))
+            {
+                while (await eventStream.ResponseStream.MoveNext(cancellationTokenSource.Token))
+                {
+                    //Convert derived event type
+                    BaseEvent e = eventStream.ResponseStream.Current;
+                    switch (e.DerivedEventCase)
+                    {
+                        case BaseEvent.DerivedEventOneofCase.None:
+                            {
+                                throw new InvalidOperationException();
+                            }
+                        case BaseEvent.DerivedEventOneofCase.PartyMemberJoinedEvent:
+                            {
+                                PartyMemberJoinedEvent derivedEvent = e.PartyMemberJoinedEvent;
+                                break;
+                            }
+                        case BaseEvent.DerivedEventOneofCase.PartyMemberLeftEvent:
+                            {
+                                PartyMemberJoinedEvent derivedEvent = e.PartyMemberJoinedEvent;
+                                break;
+                            }
+                    }
+                }
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/Aurora/Executors/HostExecutor.cs b/Aurora/Executors/HostExecutor.cs
index 001d609..e95370f 100644
--- a/Aurora/Executors/HostExecutor.cs
+++ b/Aurora/Executors/HostExecutor.cs
@@ -4,7 +4,9 @@ using System.Collections.ObjectModel;
 using Aurora.Models;
 using Aurora.Executors;
 using Aurora.Services;
-using Aurora.Proto;
+using Aurora.Proto.Party;
+using Aurora.Proto.Playback;
+using Aurora.Proto.Events;
 using Aurora.RemoteImpl;
 
 namespace Aurora.Executors
@@ -13,10 +15,12 @@ namespace Aurora.Executors
     {
         RemotePartyServiceImpl _remotePartyServiceImpl;
         RemotePlaybackServiceImpl _remotePlaybackImpl;
+        RemoteEventServiceImpl _remoteEventImpl;
         public HostExecutor()
         {
             _remotePartyServiceImpl = new RemotePartyServiceImpl();
             _remotePlaybackImpl = new RemotePlaybackServiceImpl();
+            _remoteEventImpl = new RemoteEventServiceImpl();
         }
 
         public override void Connect(string hostname)
@@ -27,6 +31,7 @@ namespace Aurora.Executors
             //Register grpc RemoteService with singleton server service
             ServerService.Instance.RegisterService(RemotePartyService.BindService(_remotePartyServiceImpl));
             ServerService.Instance.RegisterService(RemotePlaybackService.BindService(_remotePlaybackImpl));
+            ServerService.Instance.RegisterService(RemoteEventService.BindService(_remoteEventImpl));
 
             //start gRPC server
             ServerService.Instance.Start();
diff --git a/Aurora/Proto/events.proto b/Aurora/Proto/events.proto
new file mode 100644
index 0000000..461d94d
--- /dev/null
+++ b/Aurora/Proto/events.proto
@@ -0,0 +1,51 @@
+syntax = "proto3";
+
+package Aurora.Proto.Events;
+
+import "Proto/general.proto";
+import "Proto/party.proto";
+
+service RemoteEventService {
+    //Party Service
+    rpc GetEvents(Aurora.Proto.General.Empty) returns (stream BaseEvent) {};
+    rpc SubscribeToEvents(SubscribeRequest) returns(SubscriptionResponse);
+    rpc UnsubscribeFromEvents(UnsubscribeRequest) returns (SubscriptionResponse);
+    rpc UnsubscribeFromAll(UnsubscribeAllRequest) returns (SubscriptionResponse);
+}
+
+/* Subscription messages */
+message SubscribeRequest {
+    repeated EventType eventTypes = 1;
+}
+
+message UnsubscribeRequest {
+    repeated EventType eventTypes = 1;
+}
+
+message UnsubscribeAllRequest {
+}
+
+message SubscriptionResponse {
+    bool successful = 1;
+}
+
+/* Event Types */
+enum EventType {
+    PartyMemberJoined = 0;
+    PartyMemberLeft = 1;
+}
+message BaseEvent {
+    EventType eventType = 1;
+    oneof derivedEvent {
+        PartyMemberJoinedEvent partyMemberJoinedEvent = 2;
+        PartyMemberLeftEvent partyMemberLeftEvent = 3;
+    }
+}
+
+message PartyMemberJoinedEvent {
+    Aurora.Proto.Party.PartyMember member = 2;
+}
+
+message PartyMemberLeftEvent {
+    Aurora.Proto.Party.PartyMember member = 2;
+}
\ No newline at end of file
diff --git a/Aurora/Proto/general.proto b/Aurora/Proto/general.proto
index 77b62ed..684e2f3 100644
--- a/Aurora/Proto/general.proto
+++ b/Aurora/Proto/general.proto
@@ -1,10 +1,10 @@
 syntax = "proto3";
 
-package Aurora.Proto;
+package Aurora.Proto.General;
 
 message Chunk {
     bytes Content = 1;
 }
 
 message Empty{
-}
\ No newline at end of file
+}
diff --git a/Aurora/Proto/party.proto b/Aurora/Proto/party.proto
index 625ab14..5024a3e 100644
--- a/Aurora/Proto/party.proto
+++ b/Aurora/Proto/party.proto
@@ -1,6 +1,6 @@
 syntax = "proto3";
 
-package Aurora.Proto;
+package Aurora.Proto.Party;
 
 import "Proto/general.proto";
 
@@ -8,7 +8,7 @@ service RemotePartyService {
     //Party Service
     rpc JoinParty(JoinPartyRequest) returns (JoinPartyResponse);
     rpc LeaveParty(LeavePartyRequest) returns (LeavePartyResponse);
-    rpc GetPartyMembers(Empty) returns (MembersResponse);
+    rpc GetPartyMembers(Aurora.Proto.General.Empty) returns (MembersResponse);
 }
 
 message JoinPartyRequest {
diff --git a/Aurora/Proto/playback.proto b/Aurora/Proto/playback.proto
index 22b741f..64dad2e 100644
--- a/Aurora/Proto/playback.proto
+++ b/Aurora/Proto/playback.proto
@@ -1,12 +1,12 @@
 syntax = "proto3";
 
-package Aurora.Proto;
+package Aurora.Proto.Playback;
 
 import "Proto/general.proto";
 
 service RemotePlaybackService {
     //Playback Service
-    rpc GetPartyStream(Empty) returns (stream Chunk) {};
+    rpc GetPartyStream(Aurora.Proto.General.Empty) returns (stream Aurora.Proto.General.Chunk) {};
 }
 
 enum TransferStatusCode {
diff --git a/Aurora/RemoteImpl/RemoteEventImpl.cs b/Aurora/RemoteImpl/RemoteEventImpl.cs
new file mode 100644
index 0000000..2feb619
--- /dev/null
+++ b/Aurora/RemoteImpl/RemoteEventImpl.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Linq;
+using Aurora.Services;
+using Aurora.Proto.Events;
+using Aurora.Proto.General;
+
+namespace Aurora.RemoteImpl
+{
+    public class RemoteEventServiceImpl : RemoteEventService.RemoteEventServiceBase
+    {
+        public RemoteEventServiceImpl()
+        {
+
+        }
+
+        /// 
+        /// RPC for getting event stream for a particular client.
+        /// 
+        /// Empty
+        /// The response stream
+        /// gRPC client context
+        /// 
+        public async override Task GetEvents(Empty request, Grpc.Core.IServerStreamWriter responseStream, Grpc.Core.ServerCallContext context)
+        {
+            while (EventManager.Instance.GetSubscriptionCount(context.Peer) > 0)
+            {
+                List events = EventManager.Instance.GetSessionEvents(context.Peer);
+                foreach (BaseEvent currentEvent in events)
+                {
+                    await responseStream.WriteAsync(currentEvent);
+                }
+            }
+        }
+
+        /// 
+        /// RPC for subscribing to remote events
+        /// 
+        /// SubscribeRequest
+        /// gRPC client context
+        /// 
+        public override Task SubscribeToEvents(SubscribeRequest request, Grpc.Core.ServerCallContext context)
+        {
+            EventManager.Instance.AddSubscriptionList(context.Peer, request.EventTypes.ToList());
+
+            return Task.FromResult(new SubscriptionResponse { Successful = true });
+        }
+
+        /// 
+        /// RPC for unsubscibing from events
+        /// 
+        /// UnsubscribeRequest
+        /// gRPC client context
+        /// 
+        public override Task UnsubscribeFromEvents(UnsubscribeRequest request, Grpc.Core.ServerCallContext context)
+        {
+            EventType[] eventTypes = null;
+            request.EventTypes.CopyTo(eventTypes, 0);
+
+            EventManager.Instance.RemoveSubscriptionList(context.Peer, eventTypes.ToList());
+
+            return Task.FromResult(new SubscriptionResponse { Successful = true });
+        }
+
+        /// 
+        /// RPC for unsubscribing from all events
+        /// 
+        /// UnsubscribeAllRequest
+        /// gRPC client context
+        /// 
+        public override Task UnsubscribeFromAll(UnsubscribeAllRequest request, Grpc.Core.ServerCallContext context)
+        {
+            EventManager.Instance.RemoveAllSubscriptions(context.Peer);
+
+            return Task.FromResult(new SubscriptionResponse { Successful = true });
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/Aurora/RemoteImpl/RemotePartyImpl.cs b/Aurora/RemoteImpl/RemotePartyImpl.cs
index 34bb207..d58e792 100644
--- a/Aurora/RemoteImpl/RemotePartyImpl.cs
+++ b/Aurora/RemoteImpl/RemotePartyImpl.cs
@@ -2,7 +2,10 @@ using System;
 using System.Threading.Tasks;
 using System.Collections.ObjectModel;
 using System.Linq;
-using Aurora.Proto;
+using Google.Protobuf.WellKnownTypes;
+using Aurora.Proto.Party;
+using Aurora.Proto.General;
+using Aurora.Proto.Events;
 using Aurora.Models;
 using Aurora.Services;
 
@@ -39,11 +42,24 @@ namespace Aurora.RemoteImpl
 
         public override Task JoinParty(JoinPartyRequest request, Grpc.Core.ServerCallContext context)
         {
-            _partyMembers.Add(new PartyMember()
+            PartyMember partyMember = new PartyMember()
             {
                 UserName = request.UserName,
                 IpAddress = context.Host,
-            });
+            };
+
+            _partyMembers.Add(partyMember);
+
+            BaseEvent e = new BaseEvent
+            {
+                EventType = EventType.PartyMemberJoined,
+                PartyMemberJoinedEvent = new PartyMemberJoinedEvent
+                {
+                    Member = partyMember,
+                }
+            };
+
+            EventManager.Instance.PushEvent(e);
 
             JoinPartyResponse response = new JoinPartyResponse() { Status = PartyJoinedStatusEnum.Connected };
             return Task.FromResult(response);
@@ -51,12 +67,26 @@ namespace Aurora.RemoteImpl
 
         public override Task LeaveParty(LeavePartyRequest request, Grpc.Core.ServerCallContext context)
         {
-            _partyMembers.Remove(_partyMembers.Where(e => e.Id == request.ClientId).Single());
+            PartyMember partyMember = _partyMembers.Where(e => e.Id == request.ClientId).Single();
+
+            _partyMembers.Remove(partyMember);
+
+            BaseEvent bv = new BaseEvent
+            {
+                EventType = EventType.PartyMemberJoined,
+                PartyMemberLeftEvent = new PartyMemberLeftEvent
+                {
+                    Member = partyMember,
+                }
+            };
+
+            EventManager.Instance.PushEvent(bv);
+
             LeavePartyResponse response = new LeavePartyResponse() { Status = PartyJoinedStatusEnum.Disconnected };
             return Task.FromResult(response);
         }
 
-        public override Task GetPartyMembers(Empty empty, Grpc.Core.ServerCallContext context)
+        public override Task GetPartyMembers(Proto.General.Empty empty, Grpc.Core.ServerCallContext context)
         {
             MembersResponse response = new MembersResponse();
             response.Members.AddRange(_partyMembers);
diff --git a/Aurora/RemoteImpl/RemotePlaybackImpl.cs b/Aurora/RemoteImpl/RemotePlaybackImpl.cs
index 8470eb1..47b8d12 100644
--- a/Aurora/RemoteImpl/RemotePlaybackImpl.cs
+++ b/Aurora/RemoteImpl/RemotePlaybackImpl.cs
@@ -1,7 +1,8 @@
 using System;
 using System.Threading.Tasks;
 using System.IO;
-using Aurora.Proto;
+using Aurora.Proto.Playback;
+using Aurora.Proto.General;
 using Aurora.Models;
 
 namespace Aurora.RemoteImpl
@@ -14,7 +15,7 @@ namespace Aurora.RemoteImpl
 
         }
 
-        public override async Task GetPartyStream(Empty empty,
+        public override Task GetPartyStream(Empty empty,
             Grpc.Core.IServerStreamWriter responseStream,
             Grpc.Core.ServerCallContext context)
         {
diff --git a/Aurora/Services/EventManager.cs b/Aurora/Services/EventManager.cs
new file mode 100755
index 0000000..2c179df
--- /dev/null
+++ b/Aurora/Services/EventManager.cs
@@ -0,0 +1,294 @@
+using System;
+using System.IO;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Threading;
+using Google.Protobuf.WellKnownTypes;
+using Google.Protobuf.Reflection;
+using Aurora.Proto.Events;
+using Aurora.Models;
+
+namespace Aurora.Services
+{
+    public class EventManager : BaseService
+    {
+        //TODO purge inactive sessions from the list
+        public EventManager()
+        {
+            _eventQueues = new ConcurrentDictionary>();
+            _subscriptionList = new Dictionary>();
+            _unprocessedEventsList = new ObservableCollection();
+            _unprocessedEventsList.CollectionChanged += UnprocessedEventsList_Changed;
+        }
+
+        #region Fields
+        private ConcurrentDictionary> _eventQueues;
+        private Dictionary> _subscriptionList;
+        private ObservableCollection _unprocessedEventsList;
+
+
+        #endregion Fields
+
+        #region Private Methods
+        /// 
+        /// Add event to appropriate events list for subscribed sessions
+        /// 
+        /// 
+        private void ProcessEvent(BaseEvent unprocessedEvent)
+        {
+            lock (_subscriptionList)
+            {
+                lock (_unprocessedEventsList)
+                {
+                    //Duplicate events into client event queues
+                    foreach (KeyValuePair> subscription in _subscriptionList)
+                    {
+                        //Active Events contains the session in question
+                        if (_eventQueues.ContainsKey(subscription.Key))
+                        {
+                            //Add all of the events to active events that are subscribed
+
+                            if (subscription.Value.Contains(unprocessedEvent.EventType))
+                            {
+                                BlockingCollection eventList;
+                                _eventQueues.TryGetValue(subscription.Key, out eventList);
+                                if (eventList != null)
+                                {
+                                    eventList.Add(unprocessedEvent);
+                                }
+                            }
+                        }
+                    }
+
+                    //Remove Event from list
+                    _unprocessedEventsList.Remove(unprocessedEvent);
+                }
+            }
+        }
+
+        #endregion Private Methods
+
+        #region Public Methods
+        /// 
+        /// Get the list of event type subscriptions for a given session id.
+        /// 
+        /// Session Id
+        /// 
+        public List GetSubscriptionList(string session)
+        {
+            List eventList = new List();
+            if (_subscriptionList.ContainsKey(session))
+            {
+                _subscriptionList.TryGetValue(session, out eventList);
+            }
+
+            return eventList;
+        }
+
+        /// 
+        /// Get the number of event subscriptions for a given session
+        /// 
+        /// Session Id
+        /// 
+        public int GetSubscriptionCount(string session)
+        {
+            List eventList = new List();
+            if (_subscriptionList.ContainsKey(session))
+            {
+                _subscriptionList.TryGetValue(session, out eventList);
+            }
+
+            return eventList.Count();
+        }
+
+        /// 
+        /// Add a new subscription 
+        /// 
+        /// 
+        /// 
+        public bool AddSubscription(string session, EventType type)
+        {
+            bool success = false;
+            if (!_subscriptionList.ContainsKey(session))
+            {
+                //Add session to subscription list
+                List eventList = new List();
+                eventList.Add(type);
+                _subscriptionList.Add(session, eventList);
+                success = true;
+                //base.LogInformation(string.Format("Subscription removed for event type {0} subscription on session {1}", type.ToString(), session));
+            }
+            else
+            {
+                List eventList;
+                _subscriptionList.TryGetValue(session, out eventList);
+                if (eventList != null)
+                {
+                    eventList.Add(type);
+                    success = true;
+                    //base.LogInformation(string.Format("Subscription removed for event type {0} subscription on session {1}", type.ToString(), session));
+                }
+            }
+
+            //Add activeEvents if it doesn't exist
+            if (!_eventQueues.ContainsKey(session))
+            {
+                //Add session to active events
+                _eventQueues.TryAdd(session, new BlockingCollection());
+            }
+
+            return success;
+        }
+
+        /// 
+        /// Add a list of subscriptions. This unsubscribes from unused events.
+        /// 
+        /// The browser session id.
+        /// The list of event types to subscribe to.
+        public void AddSubscriptionList(string session, List types)
+        {
+            RemoveAllSubscriptions(session);
+
+            foreach (EventType e in types)
+            {
+                AddSubscription(session, e);
+            }
+        }
+
+        /// 
+        /// Unsubscribe from a given event type.
+        /// 
+        /// Session Id
+        /// Event Type to be removed
+        public void RemoveSubscription(string session, EventType type)
+        {
+            if (_subscriptionList.ContainsKey(session))
+            {
+                List eventTypeList;
+                _subscriptionList.TryGetValue(session, out eventTypeList);
+                if (eventTypeList != null && eventTypeList.Contains(type))
+                {
+                    eventTypeList.Remove(type);
+                    //base.LogInformation(string.Format("Subscription removed for event type {0} subscription on session {1}", type.ToString(), session));
+                }
+            }
+        }
+
+        public void RemoveSubscriptionList(string session, List types)
+        {
+            foreach (EventType e in types)
+            {
+                RemoveSubscription(session, e);
+            }
+        }
+
+        /// 
+        /// Remove all subscriptons for a given session.
+        /// 
+        /// Session Id
+        public void RemoveAllSubscriptions(string session)
+        {
+            if (_subscriptionList.ContainsKey(session))
+            {
+                _subscriptionList.Remove(session);
+            }
+            if (_eventQueues.ContainsKey(session))
+            {
+                BlockingCollection rem = null;
+                _eventQueues.TryRemove(session, out rem);
+            }
+
+            //base.LogInformation(string.Format("All subscriptions removed for event type {0}", session));
+        }
+
+        /// 
+        /// Get a list of accumulated events for a given session. Timeout after 5 seconds if list is empty.
+        /// 
+        /// 
+        /// List
+        public List GetSessionEvents(string session)
+        {
+            BlockingCollection eList;
+            _eventQueues.TryGetValue(session, out eList);
+
+            List returnList = new List();
+            if (eList == null)
+            {
+                return returnList;
+            }
+
+            //Continue to take until the eList is not empty.
+            while (true)
+            {
+                BaseEvent e;
+                eList.TryTake(out e);
+                if (e != null)
+                {
+                    returnList.Add(e);
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            //In the event that eList was empty to begin with, wait for something to be appear or cancel
+            if (eList.Count == 0)
+            {
+                CancellationTokenSource tkSrc = new CancellationTokenSource(5000);
+
+                BaseEvent e = null;
+                try
+                {
+                    e = eList.Take(tkSrc.Token);
+                }
+                catch (OperationCanceledException)
+                {
+                    // eat this
+                }
+                catch (Exception)
+                {
+                }
+
+                if (e != null)
+                {
+                    returnList.Add(e);
+                }
+            }
+
+            return returnList;
+        }
+
+        /// 
+        /// Push a new event to the event queue.
+        /// 
+        /// The event to be pushed
+        public void PushEvent(BaseEvent newEvent)
+        {
+            _unprocessedEventsList.Add(newEvent);
+        }
+
+        #endregion Public Methods
+
+        #region Events
+        private void UnprocessedEventsList_Changed(object sender, NotifyCollectionChangedEventArgs e)
+        {
+            switch (e.Action)
+            {
+                case NotifyCollectionChangedAction.Add:
+                    {
+                        foreach (BaseEvent bEvent in e.NewItems)
+                        {
+                            ProcessEvent(bEvent);
+                        }
+                        break;
+                    }
+            }
+        }
+
+        #endregion Events
+    }
+}
\ No newline at end of file