Inheritance: System.EventArgs
        internal void ResourceOnStreamEvent(object sender, StreamEventArgs streamEventArgs)
        {
            // Note that we can have only one update at time
            // as the current SDK's threading model calls this 
            // method using always the same thread (per object basis)

            try
            {
                var deltaMessage = streamEventArgs.Update.FromJson<StreamMessage>();
                var fixtureDelta = deltaMessage.GetContent<Fixture>();
                
                _logger.InfoFormat("{0} stream update arrived", fixtureDelta);
                if (IsDisposing)
                {
                    _logger.WarnFormat("Listener for {0} is disposing - skipping current update", _resource);
                    return;
                }

                if (!AquireLock())
                {
                    _logger.WarnFormat("Failed to acquire lock while trying to process stream update {0}", fixtureDelta);
                    return;
                }

                RaiseEvent(OnBeginStreamUpdateProcessing, null, fixtureDelta);

                if (IsDisposing)
                {
                    _logger.WarnFormat("Listener for {0} is disposing - skipping current update", _resource);
                    return;
                }

                // if there was an error from which we haven't recovered yet
                // it might be that with a new sequence, we might recover.
                // So in this case, ignore the update and grab a new 
                // snapshot.
                if (IsErrored)
                {
                    _logger.DebugFormat("Listener for {0} was in an error state - skipping update and grabbing a new snapshot", _resource);
                    IsErrored = false;
                    RetrieveAndProcessSnapshot();
                    return;
                }

                if (!IsSequenceValid(fixtureDelta))
                {
                    _logger.WarnFormat("Update for {0} will not be processed because sequence is not valid", fixtureDelta);

                    // if snapshot was already processed with higher sequence no need to process this sequence
                    // THIS should never happen!!
                    if (fixtureDelta.Sequence <= _lastSequenceProcessedInSnapshot)
                    {
                        _logger.WarnFormat("Stream update {0} will be ignored because snapshot with higher sequence={1} was already processed",
                            fixtureDelta, _lastSequenceProcessedInSnapshot);

                        return;
                    }

                    SuspendAndReprocessSnapshot();
                    return;
                }

                bool hasEpochChanged;
                var epochValid = IsEpochValid(fixtureDelta, out hasEpochChanged);

                if (epochValid)
                {
                    ProcessSnapshot(fixtureDelta, false, hasEpochChanged);
                    RaiseEvent(OnFinishedStreamUpdateProcessing);
                }
                else
                {

                    _fixtureStartTime = fixtureDelta.StartTime;

                    if (fixtureDelta.IsMatchStatusChanged && !string.IsNullOrEmpty(fixtureDelta.MatchStatus))
                    {
                        _logger.DebugFormat("{0} has changed matchStatus={1}", _resource,
                            Enum.Parse(typeof (MatchStatus), fixtureDelta.MatchStatus));
                        _platformConnector.ProcessMatchStatus(fixtureDelta);

                        RaiseEvent(OnFinishedStreamUpdateProcessing);
                    }

                    bool stopStreaming = true;
                    if ((fixtureDelta.IsMatchStatusChanged && fixtureDelta.IsMatchOver) || fixtureDelta.IsDeleted)
                    {

                        if (fixtureDelta.IsDeleted)
                        {
                            ProcessFixtureDelete(fixtureDelta);
                        }
                        else // Match Over
                        {
                            stopStreaming = ProcessMatchOver(fixtureDelta);
                        }

                        RaiseEvent(OnFinishedStreamUpdateProcessing);
                        if (stopStreaming)

                            Stop();

                        return;
                    }


                    _logger.InfoFormat("Stream update {0} will not be processed because epoch was not valid",
                        fixtureDelta);

                    SuspendAndReprocessSnapshot(hasEpochChanged);
                    return;
                }

                _logger.InfoFormat("Update fo {0} processed successfully", fixtureDelta);
            }
            catch (AggregateException ex)
            {
                int total = ex.InnerExceptions.Count;
                int count = 0;
                foreach (var innerEx in ex.InnerExceptions)
                {
                    _logger.ErrorFormat("Error processing update for {0} {1} ({2}/{3})",_resource, innerEx, ++count, total);
                }

                SetErrorState();
                RaiseEvent(OnError, ex);
            }
            catch (Exception ex)
            {
                _logger.Error(string.Format("Error processing update {0}", _resource), ex);
                SetErrorState();
                RaiseEvent(OnError, ex);
            }
            finally
            {
                ReleaseLock();
            }

        }
        private void GtpFixtureStreamEvent(object sender, StreamEventArgs e)
        {
            try
            {
                var resource = sender as IResource;

                //Notice the two-step deserialization
                var streamMessage = (StreamMessage)JsonConvert.DeserializeObject(e.Update, typeof(StreamMessage),
                                                       new JsonSerializerSettings
                                                       {
                                                           Converters = new List<JsonConverter> { new IsoDateTimeConverter() },
                                                           NullValueHandling = NullValueHandling.Ignore
                                                       });

                var fixtureDelta = streamMessage.GetContent<Fixture>();
                _logger.InfoFormat("Streaming Update arrived for {0} id {1} sequence {2}", _gtpFixture.Name, _gtpFixture.Id, fixtureDelta.Sequence);

                if (fixtureDelta.Sequence < _currentSequence)
                {
                    _logger.InfoFormat("Fixture {0} id {1} sequence {2} is less than current sequence {3}", _gtpFixture.Name, _gtpFixture.Id, fixtureDelta.Sequence, _currentSequence);
                    return;
                }
                if ((fixtureDelta.Sequence - _currentSequence) > 1)
                {
                    _logger.WarnFormat("Fixture {0} id {1} sequence {2} is more than one greater that current sequence {3}", _gtpFixture.Name, _gtpFixture.Id, fixtureDelta.Sequence, _currentSequence);
                }

                _currentSequence = fixtureDelta.Sequence;

                //If the stream epoch does not equal the current epoch,
                //then we need to pause streaming, process the snapshot, carry on streaming
                if (fixtureDelta.Epoch > _currentEpoch)
                {
                    _logger.InfoFormat("Epoch changed for {0} from {1} to {2}", _gtpFixture.Name, _currentEpoch, fixtureDelta.Epoch);
                    _currentEpoch = fixtureDelta.Epoch;

                    if (fixtureDelta.LastEpochChangeReason != null && fixtureDelta.LastEpochChangeReason.Contains((int)SSEpochChangeReason.StartTime))
                    {
                        _logger.InfoFormat("Fixture {0} has had its start time changed", _gtpFixture.Name);
                        ProcessDelta(fixtureDelta);
                    }

                    if (fixtureDelta.LastEpochChangeReason != null && fixtureDelta.LastEpochChangeReason.Contains((int)SSEpochChangeReason.Deleted))
                    {
                        _logger.InfoFormat("Fixture {0} has been deleted from the GTP Fixture Factroy. Suspending all markets and stopping the stream", _gtpFixture.Name);
                        _gtpFixture.StopStreaming();
                        SuspendAllMarkets();
                        FixtureEnded = true;
                    }
                    else
                    {
                        SuspendAndReprocessSnapshot();
                    }
                }
                else if (fixtureDelta.Epoch == _currentEpoch)
                {
                    ProcessDelta(fixtureDelta);
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
            }
        }
 public virtual void OnStreamEvent(StreamEventArgs e)
 {
     if (StreamEvent != null)
         StreamEvent(this, e);
 }