public void OnNext(KeyValuePair <string, object> value)
        {
            lock (Scopes)
            {
                var startSuffix     = ".Start";
                var stopSuffix      = ".Stop";
                var exceptionSuffix = ".Exception";

                if (value.Key.EndsWith(startSuffix))
                {
                    var          name         = value.Key.Substring(0, value.Key.Length - startSuffix.Length);
                    PropertyInfo propertyInfo = value.Value.GetType().GetProperty("Links");
                    var          links        = propertyInfo?.GetValue(value.Value) as IEnumerable <Activity> ?? Array.Empty <Activity>();

                    var scope = new ProducedDiagnosticScope()
                    {
                        Name             = name,
                        Activity         = Activity.Current,
                        Links            = links.Select(a => a.ParentId).ToList(),
                        LinkedActivities = links.ToList()
                    };

                    Scopes.Add(scope);
                }
                else if (value.Key.EndsWith(stopSuffix))
                {
                    var name = value.Key.Substring(0, value.Key.Length - stopSuffix.Length);
                    foreach (ProducedDiagnosticScope producedDiagnosticScope in Scopes)
                    {
                        if (producedDiagnosticScope.Activity.Id == Activity.Current.Id)
                        {
                            producedDiagnosticScope.IsCompleted = true;
                            return;
                        }
                    }
                    throw new InvalidOperationException($"Event '{name}' was not started");
                }
                else if (value.Key.EndsWith(exceptionSuffix))
                {
                    var name = value.Key.Substring(0, value.Key.Length - exceptionSuffix.Length);
                    foreach (ProducedDiagnosticScope producedDiagnosticScope in Scopes)
                    {
                        if (producedDiagnosticScope.Activity.Id == Activity.Current.Id)
                        {
                            if (producedDiagnosticScope.IsCompleted)
                            {
                                throw new InvalidOperationException("Scope should not be stopped when calling Failed");
                            }

                            producedDiagnosticScope.Exception = (Exception)value.Value;
                        }
                    }
                }
            }
        }
        public ProducedDiagnosticScope AssertScope(string name, params KeyValuePair <string, string>[] expectedAttributes)
        {
            ProducedDiagnosticScope scope = AssertScopeStarted(name, expectedAttributes);

            if (!scope.IsCompleted)
            {
                throw new InvalidOperationException($"'{name}' is not completed");
            }

            return(scope);
        }
        public ProducedDiagnosticScope AssertScopeException(string name, Action <Exception> action = null)
        {
            ProducedDiagnosticScope scope = AssertScopeStarted(name);

            if (scope.Exception == null)
            {
                throw new InvalidOperationException($"Scope '{name}' is not marked as failed");
            }

            action?.Invoke(scope.Exception);

            return(scope);
        }
        public void OnNext(KeyValuePair <string, object> value)
        {
            lock (Scopes)
            {
                var startSuffix     = ".Start";
                var stopSuffix      = ".Stop";
                var exceptionSuffix = ".Exception";
                if (value.Key.EndsWith(startSuffix))
                {
                    var name  = value.Key.Substring(0, value.Key.Length - startSuffix.Length);
                    var scope = new ProducedDiagnosticScope()
                    {
                        Name     = name,
                        Activity = Activity.Current
                    };
                    Scopes.Add(scope);
                }
                else if (value.Key.EndsWith(stopSuffix))
                {
                    var name = value.Key.Substring(0, value.Key.Length - stopSuffix.Length);
                    foreach (ProducedDiagnosticScope producedDiagnosticScope in Scopes)
                    {
                        if (producedDiagnosticScope.Name == name)
                        {
                            producedDiagnosticScope.IsCompleted = true;
                            return;
                        }
                    }
                    throw new InvalidOperationException($"Event '{name}' was not started");
                }
                else if (value.Key.EndsWith(exceptionSuffix))
                {
                    var name = value.Key.Substring(0, value.Key.Length - exceptionSuffix.Length);
                    foreach (ProducedDiagnosticScope producedDiagnosticScope in Scopes)
                    {
                        if (producedDiagnosticScope.IsCompleted)
                        {
                            throw new InvalidOperationException("Scope should not be stopped when calling Failed");
                        }

                        if (producedDiagnosticScope.Name == name)
                        {
                            producedDiagnosticScope.Exception = (Exception)value.Value;
                        }
                    }
                }
            }
        }