public override TryHandleRecordResult Execute(
            StandardTryHandleRecordOp operation)
        {
            operation.MustForArg(nameof(operation)).NotBeNull();

            var sqlServerLocator      = this.TryGetLocator(operation);
            var convertedRecordFilter = this.ConvertRecordFilter(operation.RecordFilter, sqlServerLocator);
            var tagIdsForEntryCsv     = this.GetIdsAddIfNecessaryTag(
                sqlServerLocator,
                operation.Tags ?? new List <NamedValue <string> >())
                                        .Select(_ => _.ToStringInvariantPreferred())
                                        .ToCsv();
            var storedProcOp = StreamSchema.Sprocs.TryHandleRecord.BuildExecuteStoredProcedureOp(
                this.Name,
                operation.Concern,
                operation.Details ?? Invariant($"Created by {nameof(StandardTryHandleRecordOp)}."),
                convertedRecordFilter,
                tagIdsForEntryCsv,
                operation.OrderRecordsBy,
                operation.MinimumInternalRecordId,
                operation.InheritRecordTags,
                operation.StreamRecordItemsToInclude);

            var sqlProtocol = this.BuildSqlOperationsProtocol(sqlServerLocator);
            var sprocResult = sqlProtocol.Execute(storedProcOp);

            int shouldHandle = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.ShouldHandle)].GetValueOfType <int>();
            int isBlocked    = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.IsBlocked)].GetValueOfType <int>();

            if (shouldHandle != 1)
            {
                return(new TryHandleRecordResult(null, isBlocked == 1));
            }

            long   internalRecordId            = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.InternalRecordId)].GetValueOfType <long>();
            int    serializerRepresentationId  = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.SerializerRepresentationId)].GetValueOfType <int>();
            int    identifierTypeWithVersionId = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.IdentifierTypeWithVersionId)].GetValueOfType <int>();
            int    objectTypeWithVersionId     = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.ObjectTypeWithVersionId)].GetValueOfType <int>();
            string stringSerializedId          = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.StringSerializedId)].GetValueOfType <string>();
            string stringSerializedObject      = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.StringSerializedObject)].GetValueOfType <string>();

            byte[]   binarySerializedObject = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.BinarySerializedObject)].GetValueOfType <byte[]>();
            DateTime recordTimestampRaw     = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.RecordDateTime)].GetValueOfType <DateTime>();
            DateTime?objectTimestampRaw     = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.ObjectDateTime)].GetValueOfType <DateTime?>();
            string   recordTagIdsCsv        = sprocResult.OutputParameters[nameof(StreamSchema.Sprocs.TryHandleRecord.OutputParamName.TagIdsCsv)].GetValueOfType <string>();

            var identifiedSerializerRepresentation = this.GetSerializerRepresentationFromId(sqlServerLocator, serializerRepresentationId);
            var identifierType = this.GetTypeById(sqlServerLocator, identifierTypeWithVersionId, true);
            var objectType     = this.GetTypeById(sqlServerLocator, objectTypeWithVersionId, true);
            var tagIds         = recordTagIdsCsv?.FromCsv().Select(_ => long.Parse(_, CultureInfo.InvariantCulture)).ToList();
            var tags           = tagIds == null ? null : this.GetTagsByIds(sqlServerLocator, tagIds);

            var recordTimestamp = recordTimestampRaw.ToUtc();

            var objectTimestamp = objectTimestampRaw == null ? (DateTime?)null : objectTimestampRaw.ToUtc();

            var metadata = new StreamRecordMetadata(
                stringSerializedId,
                identifiedSerializerRepresentation.SerializerRepresentation,
                identifierType,
                objectType,
                tags,
                recordTimestamp,
                objectTimestamp);

            DescribedSerializationBase payload;

            if (operation.StreamRecordItemsToInclude == StreamRecordItemsToInclude.MetadataAndPayload)
            {
                switch (identifiedSerializerRepresentation.SerializationFormat)
                {
                case SerializationFormat.Binary:
                    payload = new BinaryDescribedSerialization(
                        objectType.WithVersion,
                        identifiedSerializerRepresentation.SerializerRepresentation,
                        binarySerializedObject);
                    break;

                case SerializationFormat.String:
                    payload = new StringDescribedSerialization(
                        objectType.WithVersion,
                        identifiedSerializerRepresentation.SerializerRepresentation,
                        stringSerializedObject);
                    break;

                default:
                    throw new NotSupportedException(
                              Invariant($"{nameof(SerializationFormat)} {identifiedSerializerRepresentation.SerializationFormat} is not supported."));
                }
            }
            else
            {
                payload = new NullDescribedSerialization(metadata.TypeRepresentationOfObject.WithVersion, metadata.SerializerRepresentation);
            }

            var record = new StreamRecord(internalRecordId, metadata, payload);
            var result = new TryHandleRecordResult(record);

            return(result);
        }
        public override EvaluateReactionRegistrationResult Execute(
            EvaluateReactionRegistrationOp operation)
        {
            if (operation.ReactionRegistration.Dependencies.Count != 1)
            {
                throw new NotSupportedException(Invariant($"Only 1 single {typeof(RecordFilterReactorDependency)} is supported, {operation.ReactionRegistration.Dependencies.Count} were supplied."));
            }

            var dependency             = operation.ReactionRegistration.Dependencies.Single();
            var recordFilterDependency = dependency as RecordFilterReactorDependency;

            if (recordFilterDependency == null)
            {
                throw new NotSupportedException(Invariant($"Only {typeof(RecordFilterReactorDependency)} is supported, {dependency?.GetType().ToStringReadable()}."));
            }

            var reactionId = Invariant($"{operation.ReactionRegistration.Id}___{DateTime.UtcNow.ToStringInvariantPreferred()}");

            var streamRepToHandledDependencyRecordIdToBeIncludedMap = new Dictionary <IStreamRepresentation, HashSet <long> >();
            var handledRecordMementos = new List <RecordSetHandlingMemento>();
            var allRequiredSeen       = true;

            foreach (var recordFilterEntry in recordFilterDependency.Entries)
            {
                try
                {
                    var stream = this.streamFactory.Execute(new GetStreamFromRepresentationOp(recordFilterEntry.StreamRepresentation));
                    stream.MustForOp(nameof(stream)).BeAssignableToType <ISyncReturningProtocol <StandardTryHandleRecordOp, TryHandleRecordResult> >();
                    var streamProtocol = (ISyncReturningProtocol <StandardTryHandleRecordOp, TryHandleRecordResult>)stream;

                    var tryHandleConcern = EvaluateReactionRegistrationOp.BuildHandlingConcern(operation.ReactionRegistration, recordFilterEntry);

                    var          handledIds    = new HashSet <long>(); // this is because we could get duplicates...
                    StreamRecord currentRecord = null;
                    do
                    {
                        var tryHandleRecordOp = new StandardTryHandleRecordOp(
                            tryHandleConcern,
                            recordFilterEntry.RecordFilter,
                            streamRecordItemsToInclude: StreamRecordItemsToInclude.MetadataOnly,
                            tags: new[]
                        {
                            new NamedValue <string>(TagNames.PotentialReactionId, reactionId),
                        });

                        var tryHandleRecordResult = streamProtocol.Execute(tryHandleRecordOp);

                        currentRecord = tryHandleRecordResult?.RecordToHandle;
                        if (currentRecord != null)
                        {
                            handledIds.Add(currentRecord.InternalRecordId);
                        }
                    }while (currentRecord != null);

                    if (handledIds.Any())
                    {
                        var streamProtocolFactoryForActions  = (IStreamRecordHandlingProtocolFactory)stream;
                        var streamHandlingProtocolForActions = streamProtocolFactoryForActions.GetStreamRecordHandlingProtocols();

                        void CompleteAction()
                        {
                            foreach (var handledInternalRecordId in handledIds)
                            {
                                var completeHandlingOp = new CompleteRunningHandleRecordOp(
                                    handledInternalRecordId,
                                    tryHandleConcern);
                                streamHandlingProtocolForActions.Execute(
                                    completeHandlingOp);
                            }
                        }

                        void CancelAction()
                        {
                            foreach (var handledInternalRecordId in handledIds)
                            {
                                var cancelHandlingOp = new CancelRunningHandleRecordOp(
                                    handledInternalRecordId,
                                    tryHandleConcern,
                                    "Not all required dependencies present.");
                                streamHandlingProtocolForActions.Execute(
                                    cancelHandlingOp);
                            }
                        }

                        var actionableSetForTracking = new RecordSetHandlingMemento(CompleteAction, CancelAction);
                        handledRecordMementos.Add(actionableSetForTracking);

                        if (recordFilterEntry.IncludeInReaction)
                        {
                            if (streamRepToHandledDependencyRecordIdToBeIncludedMap.ContainsKey(recordFilterEntry.StreamRepresentation))
                            {
                                streamRepToHandledDependencyRecordIdToBeIncludedMap[recordFilterEntry.StreamRepresentation].AddRange(handledIds);
                            }
                            else
                            {
                                streamRepToHandledDependencyRecordIdToBeIncludedMap.Add(recordFilterEntry.StreamRepresentation, handledIds);
                            }
                        }
                    }
                    else
                    {
                        if (recordFilterEntry.RequiredForReaction && !operation.OverrideRequired)
                        {
                            allRequiredSeen = false;
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new ReactorException(Invariant($"Failed to process entry: {recordFilterEntry}."), ex, operation);
                }
            }

            EvaluateReactionRegistrationResult result;

            if (!allRequiredSeen)
            {
                foreach (var recordSetHandlingMemento in handledRecordMementos)
                {
                    recordSetHandlingMemento.CancelSet();
                }

                // no reaction created since not all requirement met.
                result = new EvaluateReactionRegistrationResult(null, new List <RecordSetHandlingMemento>());
            }
            else if (!handledRecordMementos.Any())
            {
                // no reaction created since there wasn't anything to react to.
                result = new EvaluateReactionRegistrationResult(null, new List <RecordSetHandlingMemento>());
            }
            else
            {
                var streamRepresentationToInternalRecordIdsMap =
                    streamRepToHandledDependencyRecordIdToBeIncludedMap.ToDictionary(
                        k => k.Key,
                        v => (IReadOnlyList <long>)v.Value.ToList());

                var reactionTags =
                    (operation.ReactionRegistration.Tags ?? new List <NamedValue <string> >())
                    .Union(
                        new[]
                {
                    new NamedValue <string>(
                        TagNames.ReactionRegistrationId,
                        operation.ReactionRegistration.Id),
                })
                    .ToList();

                var reactionEvent = new ReactionEvent(
                    reactionId,
                    operation.ReactionRegistration.Id,
                    operation.ReactionRegistration.ReactionContext,
                    streamRepresentationToInternalRecordIdsMap,
                    DateTime.UtcNow,
                    reactionTags);

                result = new EvaluateReactionRegistrationResult(reactionEvent, handledRecordMementos);
            }

            return(result);
        }